From f5c219983c0f60a07f1bd52b6f6071e86f35455e Mon Sep 17 00:00:00 2001 From: Robert Günzler Date: Mon, 25 Sep 2023 11:56:34 +0200 Subject: add os config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Robert Günzler --- os/etc/portage/bashrc | 53 + os/etc/portage/binrepos.conf | 3 + os/etc/portage/env/binpkg | 1 + os/etc/portage/env/compiler-clang | 14 + os/etc/portage/env/compiler-clang-15 | 14 + os/etc/portage/env/compiler-clang-warningfix | 3 + os/etc/portage/env/compiler-gcc | 12 + os/etc/portage/env/ld-bfd | 2 + os/etc/portage/env/lto | 3 + os/etc/portage/env/noclean | 1 + os/etc/portage/env/pin-sccache | 1 + os/etc/portage/env/sccache | 7 + os/etc/portage/env/sccache-cc | 2 + os/etc/portage/env/sccache-cmake | 2 + os/etc/portage/make.conf | 74 + os/etc/portage/make.profile | 1 + os/etc/portage/package.accept_keywords/dev | 1 + os/etc/portage/package.accept_keywords/ffmpeg | 1 + os/etc/portage/package.accept_keywords/gnome | 2 + os/etc/portage/package.accept_keywords/kernel | 2 + os/etc/portage/package.accept_keywords/local | 158 + os/etc/portage/package.accept_keywords/rust | 2 + os/etc/portage/package.accept_keywords/sccache | 1 + os/etc/portage/package.env/local | 59 + os/etc/portage/package.env/webkit | 1 + os/etc/portage/package.license/local | 6 + os/etc/portage/package.license/postman | 1 + os/etc/portage/package.license/printer | 1 + os/etc/portage/package.mask/gentoo-zh | 1 + os/etc/portage/package.mask/rust | 1 + os/etc/portage/package.mask/webkit | 2 + os/etc/portage/package.mask/zig | 1 + os/etc/portage/package.unmask/gnome | 2 + os/etc/portage/package.unmask/local | 1 + os/etc/portage/package.use/abi | 1 + os/etc/portage/package.use/cpuflags | 2 + os/etc/portage/package.use/gnome | 2 + os/etc/portage/package.use/introspection | 15 + os/etc/portage/package.use/local | 73 + os/etc/portage/package.use/lua | 2 + os/etc/portage/package.use/s6 | 1 + os/etc/portage/package.use/webkit | 4 + os/etc/portage/package.use/wine | 38 + ...ly-unambiguously-indicating-git-over-http.patch | 69 + .../portage/patches/app-misc/gramps/xdg-spec.patch | 627 ++ .../app-misc/lfm/0001-enable-shared-linking.patch | 96 + .../app-misc/lfm/0002-fix-inline-usage.patch | 29 + .../0001-add-relation-to-cache-and-model.patch | 242 + .../0002-allow-printing-the-raw-vtodo-card.patch | 50 + .../todoman/0003-format-list-with-hierarchy.patch | 126 + .../app-misc/todoman/0004-fix-time-tests.patch | 43 + .../0003-add-bemenu-drun-implementation.patch | 391 + ...guration-of-thematic-break-and-list-marke.patch | 134 + ...ration-option-to-enable-disable-escaping-.patch | 103 + ...ration-option-to-enable-disable-HTML-enti.patch | 77 + .../tectonic/0001-v2cli-add-exec-to-build.patch | 54 + .../0001-Color-in-svg-icons-with-text-color.patch | 142 + .../0002-allow-restoring-notifications-by-id.patch | 120 + ...n-to-run-a-hook-when-changing-temperature.patch | 120 + os/etc/portage/patches/gui-wm/sway/7226.patch | 688 ++ .../aerc/0001-templates-add-drop-function.patch | 33 + .../net-irc/senpai/0001-highlight-self.patch | 32 + .../senpai/0002-configure-highlight-self.patch | 83 + .../patches/sys-libs/efivar/add-needed-fix.patch | 28 + .../portage/patches/sys-libs/efivar/data-fix.patch | 28 + .../patches/sys-libs/efivar/segfault-fix.patch | 259 + .../silence__unw_add_dynamic_fde.patch | 15 + .../firefox/custom-pre-next-tab-shortcuts.patch | 13 + .../firefox/no-signature-force-check.patch | 8 + os/etc/portage/patches/www-client/librewolf | 1 + os/etc/portage/profile/use.mask | 3 + os/etc/portage/repos.conf/gentoo.conf | 20 + os/etc/portage/repos.conf/guru.conf | 5 + os/etc/portage/repos.conf/librewolf.conf | 5 + os/etc/portage/repos.conf/robertgzr.conf | 2 + os/etc/portage/repos.conf/zh.conf | 5 + .../portage/savedconfig/sys-firmware/ipxe-1.21.1 | 5 + .../savedconfig/sys-kernel/gentoo-kernel-6.1.53-r1 | 10302 ++++++++++++++++++ .../savedconfig/sys-kernel/gentoo-kernel-6.5.4 | 10481 +++++++++++++++++++ .../savedconfig/sys-kernel/linux-firmware-20230804 | 3398 ++++++ 80 files changed, 28411 insertions(+) create mode 100644 os/etc/portage/bashrc create mode 100644 os/etc/portage/binrepos.conf create mode 100644 os/etc/portage/env/binpkg create mode 100644 os/etc/portage/env/compiler-clang create mode 100644 os/etc/portage/env/compiler-clang-15 create mode 100644 os/etc/portage/env/compiler-clang-warningfix create mode 100644 os/etc/portage/env/compiler-gcc create mode 100644 os/etc/portage/env/ld-bfd create mode 100644 os/etc/portage/env/lto create mode 100644 os/etc/portage/env/noclean create mode 100644 os/etc/portage/env/pin-sccache create mode 100644 os/etc/portage/env/sccache create mode 100644 os/etc/portage/env/sccache-cc create mode 100644 os/etc/portage/env/sccache-cmake create mode 100644 os/etc/portage/make.conf create mode 120000 os/etc/portage/make.profile create mode 100644 os/etc/portage/package.accept_keywords/dev create mode 100644 os/etc/portage/package.accept_keywords/ffmpeg create mode 100644 os/etc/portage/package.accept_keywords/gnome create mode 100644 os/etc/portage/package.accept_keywords/kernel create mode 100644 os/etc/portage/package.accept_keywords/local create mode 100644 os/etc/portage/package.accept_keywords/rust create mode 100644 os/etc/portage/package.accept_keywords/sccache create mode 100644 os/etc/portage/package.env/local create mode 100644 os/etc/portage/package.env/webkit create mode 100644 os/etc/portage/package.license/local create mode 100644 os/etc/portage/package.license/postman create mode 100644 os/etc/portage/package.license/printer create mode 100644 os/etc/portage/package.mask/gentoo-zh create mode 100644 os/etc/portage/package.mask/rust create mode 100644 os/etc/portage/package.mask/webkit create mode 100644 os/etc/portage/package.mask/zig create mode 100644 os/etc/portage/package.unmask/gnome create mode 100644 os/etc/portage/package.unmask/local create mode 100644 os/etc/portage/package.use/abi create mode 100644 os/etc/portage/package.use/cpuflags create mode 100644 os/etc/portage/package.use/gnome create mode 100644 os/etc/portage/package.use/introspection create mode 100644 os/etc/portage/package.use/local create mode 100644 os/etc/portage/package.use/lua create mode 100644 os/etc/portage/package.use/s6 create mode 100644 os/etc/portage/package.use/webkit create mode 100644 os/etc/portage/package.use/wine create mode 100644 os/etc/portage/patches/app-containers/buildkit/0001-allow-clearly-unambiguously-indicating-git-over-http.patch create mode 100644 os/etc/portage/patches/app-misc/gramps/xdg-spec.patch create mode 100644 os/etc/portage/patches/app-misc/lfm/0001-enable-shared-linking.patch create mode 100644 os/etc/portage/patches/app-misc/lfm/0002-fix-inline-usage.patch create mode 100644 os/etc/portage/patches/app-misc/todoman/0001-add-relation-to-cache-and-model.patch create mode 100644 os/etc/portage/patches/app-misc/todoman/0002-allow-printing-the-raw-vtodo-card.patch create mode 100644 os/etc/portage/patches/app-misc/todoman/0003-format-list-with-hierarchy.patch create mode 100644 os/etc/portage/patches/app-misc/todoman/0004-fix-time-tests.patch create mode 100644 os/etc/portage/patches/dev-libs/bemenu/0003-add-bemenu-drun-implementation.patch create mode 100644 os/etc/portage/patches/dev-python/mdformat/0001-Allow-configuration-of-thematic-break-and-list-marke.patch create mode 100644 os/etc/portage/patches/dev-python/mdformat/0002-Add-configuration-option-to-enable-disable-escaping-.patch create mode 100644 os/etc/portage/patches/dev-python/mdformat/0003-Add-configuration-option-to-enable-disable-HTML-enti.patch create mode 100644 os/etc/portage/patches/dev-tex/tectonic/0001-v2cli-add-exec-to-build.patch create mode 100644 os/etc/portage/patches/gui-apps/mako/0001-Color-in-svg-icons-with-text-color.patch create mode 100644 os/etc/portage/patches/gui-apps/mako/0002-allow-restoring-notifications-by-id.patch create mode 100644 os/etc/portage/patches/gui-apps/wlsunset/0001-Add-option-to-run-a-hook-when-changing-temperature.patch create mode 100644 os/etc/portage/patches/gui-wm/sway/7226.patch create mode 100644 os/etc/portage/patches/mail-client/aerc/0001-templates-add-drop-function.patch create mode 100644 os/etc/portage/patches/net-irc/senpai/0001-highlight-self.patch create mode 100644 os/etc/portage/patches/net-irc/senpai/0002-configure-highlight-self.patch create mode 100644 os/etc/portage/patches/sys-libs/efivar/add-needed-fix.patch create mode 100644 os/etc/portage/patches/sys-libs/efivar/data-fix.patch create mode 100644 os/etc/portage/patches/sys-libs/efivar/segfault-fix.patch create mode 100644 os/etc/portage/patches/sys-libs/llvm-libunwind/silence__unw_add_dynamic_fde.patch create mode 100644 os/etc/portage/patches/www-client/firefox/custom-pre-next-tab-shortcuts.patch create mode 100644 os/etc/portage/patches/www-client/firefox/no-signature-force-check.patch create mode 120000 os/etc/portage/patches/www-client/librewolf create mode 100644 os/etc/portage/profile/use.mask create mode 100644 os/etc/portage/repos.conf/gentoo.conf create mode 100644 os/etc/portage/repos.conf/guru.conf create mode 100644 os/etc/portage/repos.conf/librewolf.conf create mode 100644 os/etc/portage/repos.conf/robertgzr.conf create mode 100644 os/etc/portage/repos.conf/zh.conf create mode 100644 os/etc/portage/savedconfig/sys-firmware/ipxe-1.21.1 create mode 100644 os/etc/portage/savedconfig/sys-kernel/gentoo-kernel-6.1.53-r1 create mode 100644 os/etc/portage/savedconfig/sys-kernel/gentoo-kernel-6.5.4 create mode 100644 os/etc/portage/savedconfig/sys-kernel/linux-firmware-20230804 (limited to 'os/etc/portage') diff --git a/os/etc/portage/bashrc b/os/etc/portage/bashrc new file mode 100644 index 0000000..08e3687 --- /dev/null +++ b/os/etc/portage/bashrc @@ -0,0 +1,53 @@ +pre_pkg_setup() { + if [ -n "$DEBUG" ]; then + ewarn + ewarn "MAKEOPTS: ${MAKEOPTS}" + ewarn "CHOST: ${CHOST}" + ewarn "CC: ${CC}" + ewarn "CXX: ${CXX}" + ewarn "CFLAGS: ${CFLAGS}" + ewarn "CXXFLAGS: ${CXXFLAGS}" + ewarn "LDFLAGS: ${LDFLAGS}" + ewarn + fi +} + +pre_src_compile() { + if [ -n "$SCCACHE_ENABLED" ]; then + if [[ $SCCACHE_DIR == $PORTAGE_TMPDIR/sccache ]]; then + export SCCACHE_DIR=$PORTAGE_TMPDIR/sccache/$CATEGORY/$PN:$SLOT + mkdir -p $SCCACHE_DIR || die + fi + if ! pidof sccache 2>&1 >/dev/null; then + einfo "$(sccache --start-server)" + fi + fi +} + +post_src_compile() { + if [ -n "$SCCACHE_ENABLED" ]; then + if pidof sccache 2>&1 >/dev/null; then + einfo "$(sccache --stop-server)" + fi + fi +} + +post_pkg_postinst() { + if [ -n "$DEBUG" ]; then + ewarn + ewarn "MAKEOPTS: ${MAKEOPTS}" + ewarn "CHOST: ${CHOST}" + ewarn "CC: ${CC}" + ewarn "CXX: ${CXX}" + ewarn "CFLAGS: ${CFLAGS}" + ewarn "CXXFLAGS: ${CXXFLAGS}" + ewarn "LDFLAGS: ${LDFLAGS}" + ewarn + fi + + if [[ "$PN" = "sys-apps/s6" ]]; then + ebegin "Rebuilding service database" + sh /etc/s6-rc/reload + eend $? + fi +} diff --git a/os/etc/portage/binrepos.conf b/os/etc/portage/binrepos.conf new file mode 100644 index 0000000..566dbfb --- /dev/null +++ b/os/etc/portage/binrepos.conf @@ -0,0 +1,3 @@ +[binhost] +priority = 9999 +sync-uri = https://mirror.eu.oneandone.net/linux/distributions/gentoo/gentoo/experimental/amd64/binpkg/default/linux/17.1/x86-64/ diff --git a/os/etc/portage/env/binpkg b/os/etc/portage/env/binpkg new file mode 100644 index 0000000..48c36a4 --- /dev/null +++ b/os/etc/portage/env/binpkg @@ -0,0 +1 @@ +EMERGE_DEFAULT_OPTS="${EMERGE_DEFAULT_OPTS} --binpkg-respect-use=y --getbinpkgonly=y" diff --git a/os/etc/portage/env/compiler-clang b/os/etc/portage/env/compiler-clang new file mode 100644 index 0000000..e9d9cf4 --- /dev/null +++ b/os/etc/portage/env/compiler-clang @@ -0,0 +1,14 @@ +COMMON_FLAGS="-march=alderlake -O2 -pipe" +CFLAGS="${COMMON_FLAGS} ${CFLAGS}" +CXXFLAGS="${COMMON_FLAGS} ${CXXFLAGS}" +LDFLAGS="-fuse-ld=lld -rtlib=compiler-rt -unwindlib=libunwind -Wl,--as-needed ${LDFLAGS}" + +CC="clang" +CXX="clang++" +AR="llvm-ar" +NM="llvm-nm" +RANLIB="llvm-ranlib" +OBJCOPY="llvm-objcopy" + +# This is added to make options by linux-mod.eclass +BUILD_FIXES="LLVM=1 LLVM_IAS=1" diff --git a/os/etc/portage/env/compiler-clang-15 b/os/etc/portage/env/compiler-clang-15 new file mode 100644 index 0000000..27afffd --- /dev/null +++ b/os/etc/portage/env/compiler-clang-15 @@ -0,0 +1,14 @@ +COMMON_FLAGS="-march=alderlake -O2 -pipe" +CFLAGS="${COMMON_FLAGS} ${CFLAGS}" +CXXFLAGS="${COMMON_FLAGS} ${CXXFLAGS}" +LDFLAGS="-fuse-ld=lld -rtlib=compiler-rt -unwindlib=libunwind -Wl,--as-needed ${LDFLAGS}" + +CC="clang-15" +CXX="clang++-15" +AR="llvm-ar" +NM="llvm-nm" +RANLIB="llvm-ranlib" +OBJCOPY="llvm-objcopy" + +# This is added to make options by linux-mod.eclass +BUILD_FIXES="LLVM=1 LLVM_IAS=1" diff --git a/os/etc/portage/env/compiler-clang-warningfix b/os/etc/portage/env/compiler-clang-warningfix new file mode 100644 index 0000000..f6393d0 --- /dev/null +++ b/os/etc/portage/env/compiler-clang-warningfix @@ -0,0 +1,3 @@ +COMMON_FLAGS="${COMMON_FLAGS} -Wno-error=unused-but-set-variable,parentheses,single-bit-bitfield-constant-conversion,pointer-sign" +CFLAGS="${COMMON_FLAGS}" +CXXFLAGS="${COMMON_FLAGS}" diff --git a/os/etc/portage/env/compiler-gcc b/os/etc/portage/env/compiler-gcc new file mode 100644 index 0000000..db9c5e9 --- /dev/null +++ b/os/etc/portage/env/compiler-gcc @@ -0,0 +1,12 @@ +COMMON_FLAGS="-march=alderlake -O2 -pipe" +CFLAGS="${COMMON_FLAGS} ${CFLAGS}" +CXXFLAGS="${COMMON_FLAGS} ${CXXFLAGS}" +LDFLAGS="-fuse-ld=bfd -Wl,-O2 -Wl,--as-needed ${LDFLAGS}" + +CC="gcc" +CXX="g++" + +AR="ar" +NM="nm" +RANLIB="ranlib" +OBJCOPY="objcopy" diff --git a/os/etc/portage/env/ld-bfd b/os/etc/portage/env/ld-bfd new file mode 100644 index 0000000..38a7306 --- /dev/null +++ b/os/etc/portage/env/ld-bfd @@ -0,0 +1,2 @@ +LD="bfd" +LDFLAGS="${LDFLAGS} -fuse-ld=bfd" diff --git a/os/etc/portage/env/lto b/os/etc/portage/env/lto new file mode 100644 index 0000000..d8fa211 --- /dev/null +++ b/os/etc/portage/env/lto @@ -0,0 +1,3 @@ +CFLAGS="${CFLAGS} -Ofast -flto=thin" +CXXFLAGS="${CXXFLAGS} -Ofast -flto=thin" +LDFLAGS="${LDFLAGS} -fuse-ld=lld -Wl,-O2 -Wl,--as-needed" diff --git a/os/etc/portage/env/noclean b/os/etc/portage/env/noclean new file mode 100644 index 0000000..d4e9b3d --- /dev/null +++ b/os/etc/portage/env/noclean @@ -0,0 +1 @@ +FEATURES="${FEATURES} noclean" \ No newline at end of file diff --git a/os/etc/portage/env/pin-sccache b/os/etc/portage/env/pin-sccache new file mode 100644 index 0000000..4c918a9 --- /dev/null +++ b/os/etc/portage/env/pin-sccache @@ -0,0 +1 @@ +EGIT_OVERRIDE_COMMIT_MOZILLA_SCCACHE=46553736b11d38419a220446389d0f086fdde0f4 # https://github.com/mozilla/sccache/releases/tag/v0.4.0-pre.6 diff --git a/os/etc/portage/env/sccache b/os/etc/portage/env/sccache new file mode 100644 index 0000000..622c4c8 --- /dev/null +++ b/os/etc/portage/env/sccache @@ -0,0 +1,7 @@ +SCCACHE_ENABLED=1 + +SCCACHE_DIR=$PORTAGE_TMPDIR/sccache +SCCACHE_CACHE_SIZE=10G +SCCACHE_MAX_FRAME_LENGTH=104857600 + +RUSTC_WRAPPER="/usr/bin/sccache" diff --git a/os/etc/portage/env/sccache-cc b/os/etc/portage/env/sccache-cc new file mode 100644 index 0000000..849e458 --- /dev/null +++ b/os/etc/portage/env/sccache-cc @@ -0,0 +1,2 @@ +CC="sccache ${CC}" +CXX="sccache ${CXX}" diff --git a/os/etc/portage/env/sccache-cmake b/os/etc/portage/env/sccache-cmake new file mode 100644 index 0000000..7da1a52 --- /dev/null +++ b/os/etc/portage/env/sccache-cmake @@ -0,0 +1,2 @@ +CMAKE_CC_COMPILER_LAUNCHER="/usr/bin/sccache" +CMAKE_CXX_COMPILER_LAUNCHER="/usr/bin/sccache" diff --git a/os/etc/portage/make.conf b/os/etc/portage/make.conf new file mode 100644 index 0000000..6baa5e7 --- /dev/null +++ b/os/etc/portage/make.conf @@ -0,0 +1,74 @@ +# These settings were set by the catalyst build script that automatically +# built this stage. +# Please consult /usr/share/portage/config/make.conf.example for a more +# detailed example. + +# -march: generate code that may not run at all on processors other than the one indicated +# ref: http://web.archive.org/web/20221114110503/https://lemire.me/blog/2018/07/25/it-is-more-complicated-than-i-thought-mtune-march-in-gcc/ +COMMON_FLAGS="-march=alderlake -O2 -pipe" +CFLAGS="${COMMON_FLAGS}" +CXXFLAGS="${COMMON_FLAGS}" +FCFLAGS="${COMMON_FLAGS}" +FFLAGS="${COMMON_FLAGS}" +RUSTFLAGS="-C target-cpu=alderlake" + +# NOTE: This stage was built with the bindist Use flag enabled +PORTDIR="/var/db/repos/gentoo" +DISTDIR="/var/cache/distfiles" +PKGDIR="/var/cache/binpkgs" + +# This sets the language of build output to English. +# Please keep this setting intact when reporting bugs. +LC_MESSAGES=C + +# Set loglevel +PORTAGE_ELOG_CLASSES="error warn info log" # qa" +# Set log location +# echo: stdout after emerge +# save: /var/log/portage/elog +PORTAGE_ELOG_SYSTEM="echo save" + +# Enable extra features +# split-elog: logs under $LOGDIR/elog are split into subdirectories +# parallel-fetch: fetch in the background while compiling +# +# TODO: investigate sandbox{-*,} features +FEATURES="split-elog parallel-fetch" + +# Filter stable versions +ACCEPT_KEYWORDS=amd64 +# Filter all but licenses in the FREE group +ACCEPT_LICENSE="-* @FREE" + +# Maximise CPU usage during emerge +EMERGE_DEFAULT_OPTS="--jobs=18 --load-average=19" +MAKEOPTS="-j18 -l19" + +# Hardware settings +VIDEO_CARDS="intel i965 iris" +INPUT_DEVICES="libinput" + +# Global USE flags +USE="" +USE="$USE wayland -X" +USE="$USE -qt -qt5 -gnome -gtk" +USE="$USE vaapi" +USE="$USE vulkan" +USE="$USE gles2 gles2-only" +USE="$USE ffmpeg -gstreamer" +USE="$USE pipewire -pulseaudio -alsa" +USE="$USE -pam -policykit" +USE="$USE -consolekit -systemd" +USE="$USE -networkmanager" +USE="$USE -gnome-keyring" +USE="$USE otf -ttf" +USE="$USE -nls" +USE="$USE -introspection -vala" +USE="$USE -examples" + +# GENTOO_MIRRORS="https://mirror.eu.oneandone.net/linux/distributions/gentoo/gentoo/ https://ftp.fau.de/gentoo https://distfiles.gentoo.org" +GENTOO_MIRRORS="https://distfiles.gentoo.org" + +INSTALL_MASK="" +INSTALL_MASK="$INSTALL_MASK /lib/systemd/network /lib/systemd/system" +INSTALL_MASK="$INSTALL_MASK /usr/share/zsh" diff --git a/os/etc/portage/make.profile b/os/etc/portage/make.profile new file mode 120000 index 0000000..d5a2d98 --- /dev/null +++ b/os/etc/portage/make.profile @@ -0,0 +1 @@ +../../var/db/repos/gentoo/profiles/default/linux/amd64/17.1/clang \ No newline at end of file diff --git a/os/etc/portage/package.accept_keywords/dev b/os/etc/portage/package.accept_keywords/dev new file mode 100644 index 0000000..adcdec9 --- /dev/null +++ b/os/etc/portage/package.accept_keywords/dev @@ -0,0 +1 @@ +dev-libs/utfcpp ** diff --git a/os/etc/portage/package.accept_keywords/ffmpeg b/os/etc/portage/package.accept_keywords/ffmpeg new file mode 100644 index 0000000..0bc9beb --- /dev/null +++ b/os/etc/portage/package.accept_keywords/ffmpeg @@ -0,0 +1 @@ +<=media-video/ffmpeg-6 ~amd64 diff --git a/os/etc/portage/package.accept_keywords/gnome b/os/etc/portage/package.accept_keywords/gnome new file mode 100644 index 0000000..2b90234 --- /dev/null +++ b/os/etc/portage/package.accept_keywords/gnome @@ -0,0 +1,2 @@ +=gui-libs/gtk-4.12* ~amd64 +=gui-libs/libadwaita-1.4* ~amd64 diff --git a/os/etc/portage/package.accept_keywords/kernel b/os/etc/portage/package.accept_keywords/kernel new file mode 100644 index 0000000..7778eb9 --- /dev/null +++ b/os/etc/portage/package.accept_keywords/kernel @@ -0,0 +1,2 @@ +# =dev-lang/zig-0.11.0 diff --git a/os/etc/portage/package.unmask/gnome b/os/etc/portage/package.unmask/gnome new file mode 100644 index 0000000..6230b68 --- /dev/null +++ b/os/etc/portage/package.unmask/gnome @@ -0,0 +1,2 @@ +=gui-libs/gtk-4.12* +=gui-libs/libadwaita-1.4* diff --git a/os/etc/portage/package.unmask/local b/os/etc/portage/package.unmask/local new file mode 100644 index 0000000..2c72117 --- /dev/null +++ b/os/etc/portage/package.unmask/local @@ -0,0 +1 @@ +app-i18n/*::gentoo-zh diff --git a/os/etc/portage/package.use/abi b/os/etc/portage/package.use/abi new file mode 100644 index 0000000..396c38e --- /dev/null +++ b/os/etc/portage/package.use/abi @@ -0,0 +1 @@ +app-arch/zstd ABI_X86: 32 diff --git a/os/etc/portage/package.use/cpuflags b/os/etc/portage/package.use/cpuflags new file mode 100644 index 0000000..deaeb59 --- /dev/null +++ b/os/etc/portage/package.use/cpuflags @@ -0,0 +1,2 @@ +# framwork laptop; 11th gen intel +*/* CPU_FLAGS_X86: aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt rdrand sha sse sse2 sse3 sse4_1 sse4_2 ssse3 diff --git a/os/etc/portage/package.use/gnome b/os/etc/portage/package.use/gnome new file mode 100644 index 0000000..3c5c1f4 --- /dev/null +++ b/os/etc/portage/package.use/gnome @@ -0,0 +1,2 @@ +gui-libs/gtk introspection gstreamer +gui-libs/libadwaita introspection vala diff --git a/os/etc/portage/package.use/introspection b/os/etc/portage/package.use/introspection new file mode 100644 index 0000000..9e2f9c8 --- /dev/null +++ b/os/etc/portage/package.use/introspection @@ -0,0 +1,15 @@ +# required by: +# app-misc/gramps +# media-sound/g4music + +app-accessibility/at-spi2-core introspection +gui-libs/gtk introspection +gui-libs/libadwaita introspection vala +media-libs/graphene introspection +media-libs/gst-plugins-bad introspection +media-libs/gst-plugins-base introspection +media-libs/gstreamer introspection +media-libs/harfbuzz introspection +x11-libs/gdk-pixbuf introspection +x11-libs/gtk+:3 introspection +x11-libs/pango introspection diff --git a/os/etc/portage/package.use/local b/os/etc/portage/package.use/local new file mode 100644 index 0000000..d84d40f --- /dev/null +++ b/os/etc/portage/package.use/local @@ -0,0 +1,73 @@ +app-admin/doas persist +app-arch/brotli python +app-emulation/qemu spice smartcard virtfs usbredir sdl virgl opengl gtk udev -curl -oss QEMU_SOFTMMU_TARGETS: aarch64 +app-emulation/spice smartcard +app-i18n/fcitx -enchant +app-i18n/fcitx-qt qt5 +app-misc/clifm emoji fzf icons +app-misc/vifm -vim -vim-syntax +app-text/poppler cairo -jpeg2k +app-text/tessdata_best L10N: de en ja +app-text/tesseract -openmp +app-text/xmlto text +dev-lang/python lto +dev-lang/rust-bin clippy rust-analyzer rust-src rustfmt +dev-lang/zig doc +dev-libs/jemalloc lazy-lock xmalloc +dev-libs/libjcat -man +dev-libs/libportal gtk +dev-libs/libusb udev +dev-python/goprocam webcam +dev-qt/qtgui egl eglfs jpeg +dev-util/android-tools udev +dev-util/lldb -python -xml +dev-vcs/git -perl -webdav +gui-apps/grim jpeg +gui-apps/kanshi varlink +gui-apps/swaylock pam +gui-apps/waybar -logind evdev experimental network tray wifi +gui-libs/gtk gstreamer +gui-libs/wlroots X liftoff +gui-wm/sway X -swaybar +media-fonts/iosevka aile etoile ss04 +media-fonts/noto cjk +media-gfx/chafa -tools +media-gfx/imagemagick jpeg webp +media-libs/gst-plugins-bad -orc +media-libs/gst-plugins-base -orc -vorbis +media-libs/gst-plugins-good -orc +media-libs/gstreamer -orc +media-libs/leptonica jpeg png webp +media-libs/libepoxy X +media-libs/libglvnd X +media-libs/libpulse -asyncns +media-libs/libsndfile minimal +media-libs/mesa X +media-libs/vips pdf webp +media-sound/pulseaudio -glib +media-sound/spotify libnotify pulseaudio +media-video/ffmpeg libaom rav1e v4l vpx opus x264 +media-video/obs-studio fdk truetype v4l websocket +media-video/pipewire extra ffmpeg bluetooth dbus pipewire-alsa flatpak echo-cancel sound-server v4l jack-sdk +media-video/v4l2loopback dist-kernel +net-libs/gnutls -zstd zlib pkcs11 +net-misc/connman iwd wireguard +net-print/cups-filters -postscript +net-wireless/bluez experimental +net-wireless/iwd -monitor standalone +sys-apps/eza man +sys-apps/fwupd minimal bluetooth nvme -uefi -tpm -gnutls -gusb +sys-apps/util-linux -su +sys-apps/xdg-desktop-portal screencast +sys-auth/seatd builtin server +sys-devel/gcc graphite lto +sys-devel/lld zstd +sys-devel/llvm zstd +sys-fs/lvm2 lvm +sys-kernel/linux-firmware compress-zstd +sys-libs/zlib minizip +sys-power/suspend -crypt -lzo +virtual/libusb udev +www-client/librewolf screencast dbus hwaccel lto +x11-libs/gdk-pixbuf jpeg +x11-misc/j4-dmenu-desktop -dmenu diff --git a/os/etc/portage/package.use/lua b/os/etc/portage/package.use/lua new file mode 100644 index 0000000..8bec217 --- /dev/null +++ b/os/etc/portage/package.use/lua @@ -0,0 +1,2 @@ +dev-lua/* LUA_TARGETS: luajit -lua5-1 +dev-util/lua-language-server LUA_TARGETS: luajit -lua5-1 diff --git a/os/etc/portage/package.use/s6 b/os/etc/portage/package.use/s6 new file mode 100644 index 0000000..4257228 --- /dev/null +++ b/os/etc/portage/package.use/s6 @@ -0,0 +1 @@ +sys-apps/s6-linux-init sysv-utils diff --git a/os/etc/portage/package.use/webkit b/os/etc/portage/package.use/webkit new file mode 100644 index 0000000..741f7be --- /dev/null +++ b/os/etc/portage/package.use/webkit @@ -0,0 +1,4 @@ +*/* RUBY_TARGETS: ruby31 +dev-lang/ruby -rdoc +net-libs/webkit-gtk -jpeg2k gles2-only libnotify gstreamer +media-libs/harfbuzz icu diff --git a/os/etc/portage/package.use/wine b/os/etc/portage/package.use/wine new file mode 100644 index 0000000..618ff02 --- /dev/null +++ b/os/etc/portage/package.use/wine @@ -0,0 +1,38 @@ +# app-emulation/wine-proton ABI_X86: -32 +# app-emulation/wine-gecko ABI_X86: -32 +# app-emulation/wine-mono ABI_X86: -32 +# dev-util/mingw64-toolchain ABI_X86: -32 +# # app-emulation/vkd3d ABI_X86: 32 +# # media-libs/fontconfig ABI_X86: 32 +# # media-libs/freetype ABI_X86: 32 +# # media-libs/vulkan-loader ABI_X86: 32 +# # media-libs/libpulse ABI_X86: 32 +# app-text/xmlto text +# # media-libs/libsndfile ABI_X86: 32 +# # app-arch/bzip2 ABI_X86: 32 +# # media-libs/libpng ABI_X86: 32 +# media-libs/libsdl2 haptic # ABI_X86: 32 +# # dev-libs/wayland ABI_X86: 32 +# # media-libs/mesa ABI_X86: 32 +# # media-libs/libglvnd ABI_X86: 32 +# # x11-libs/libXcursor ABI_X86: 32 +# # x11-libs/libXfixes ABI_X86: 32 +# # x11-libs/libXi ABI_X86: 32 +# # x11-libs/libXrandr ABI_X86: 32 +# # x11-libs/libXrender ABI_X86: 32 +# # x11-libs/libXxf86vm ABI_X86: 32 +# # x11-libs/libXcomposite ABI_X86: 32 +# # x11-libs/libX11 ABI_X86: 32 +# # x11-libs/libXext ABI_X86: 32 +# # x11-libs/libxcb ABI_X86: 32 +# # x11-libs/libXau ABI_X86: 32 +# # x11-libs/libXdmcp ABI_X86: 32 +# # dev-libs/libbsd ABI_X86: 32 +# # app-crypt/libmd ABI_X86: 32 +# # dev-libs/libgcrypt ABI_X86: 32 +# # net-libs/gnutls ABI_X86: 32 +# # dev-libs/gmp ABI_X86: 32 +# # net-dns/libidn2 ABI_X86: 32 +# # dev-libs/libunistring ABI_X86: 32 +# # dev-libs/libtasn1 ABI_X86: 32 +# # dev-libs/nettle ABI_X86: 32 diff --git a/os/etc/portage/patches/app-containers/buildkit/0001-allow-clearly-unambiguously-indicating-git-over-http.patch b/os/etc/portage/patches/app-containers/buildkit/0001-allow-clearly-unambiguously-indicating-git-over-http.patch new file mode 100644 index 0000000..3643636 --- /dev/null +++ b/os/etc/portage/patches/app-containers/buildkit/0001-allow-clearly-unambiguously-indicating-git-over-http.patch @@ -0,0 +1,69 @@ +From 4020f97347a103d53ccef27c6e69e92244712385 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Tue, 16 May 2023 11:42:49 +0900 +Subject: [PATCH] allow clearly unambiguously indicating git over http(s) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + util/gitutil/git_protocol.go | 16 ++++++++++++---- + util/gitutil/git_ref.go | 2 +- + 2 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/util/gitutil/git_protocol.go b/util/gitutil/git_protocol.go +index 3b9df839..a140a6d6 100644 +--- a/util/gitutil/git_protocol.go ++++ b/util/gitutil/git_protocol.go +@@ -11,16 +11,20 @@ const ( + HTTPSProtocol + SSHProtocol + GitProtocol ++ GitHTTPProtocol ++ GitHTTPSProtocol + UnknownProtocol + ) + + // ParseProtocol parses a git URL and returns the remote url and protocol type + func ParseProtocol(remote string) (string, int) { + prefixes := map[string]int{ +- "http://": HTTPProtocol, +- "https://": HTTPSProtocol, +- "git://": GitProtocol, +- "ssh://": SSHProtocol, ++ "http://": HTTPProtocol, ++ "https://": HTTPSProtocol, ++ "git://": GitProtocol, ++ "ssh://": SSHProtocol, ++ "git+http://": GitHTTPProtocol, ++ "git+https://": GitHTTPSProtocol, + } + protocolType := UnknownProtocol + for prefix, potentialType := range prefixes { +@@ -42,5 +46,9 @@ func ParseProtocol(remote string) (string, int) { + } + } + ++ if protocolType == GitHTTPProtocol || protocolType == GitHTTPSProtocol { ++ remote = strings.TrimLeft(remote, "git+") ++ } ++ + return remote, protocolType + } +diff --git a/util/gitutil/git_ref.go b/util/gitutil/git_ref.go +index da15b8aa..1d15ce21 100644 +--- a/util/gitutil/git_ref.go ++++ b/util/gitutil/git_ref.go +@@ -54,7 +54,7 @@ func ParseGitRef(ref string) (*GitRef, error) { + if strings.HasPrefix(ref, "github.com/") { + res.IndistinguishableFromLocal = true // Deprecated + } else { +- _, proto := ParseProtocol(ref) ++ ref, proto := ParseProtocol(ref) + switch proto { + case UnknownProtocol: + return nil, errdefs.ErrInvalidArgument +-- +2.39.3 + diff --git a/os/etc/portage/patches/app-misc/gramps/xdg-spec.patch b/os/etc/portage/patches/app-misc/gramps/xdg-spec.patch new file mode 100644 index 0000000..97879a3 --- /dev/null +++ b/os/etc/portage/patches/app-misc/gramps/xdg-spec.patch @@ -0,0 +1,627 @@ +From b554ba7d23e1b5146f3babc5bb326d0c1a3d1c00 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= +Date: Tue, 8 Mar 2022 21:52:49 +0100 +Subject: [PATCH 1/4] Remove unused constant ENV_DIR + +--- + gramps/cli/argparser.py | 3 +-- + gramps/gen/const.py | 4 +--- + 2 files changed, 2 insertions(+), 5 deletions(-) + +diff --git a/gramps/cli/argparser.py b/gramps/cli/argparser.py +index f0fcab9948..e13bbd4ec3 100644 +--- a/gramps/cli/argparser.py ++++ b/gramps/cli/argparser.py +@@ -48,7 +48,7 @@ + # + #------------------------------------------------------------------------- + from gramps.gen.const import (LONGOPTS, SHORTOPTS, USER_PLUGINS, VERSION_DIR, +- HOME_DIR, TEMP_DIR, THUMB_DIR, ENV_DIR, USER_CSS) ++ HOME_DIR, TEMP_DIR, THUMB_DIR, USER_CSS) + from gramps.gen.utils.cast import get_type_converter + from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext +@@ -425,7 +425,6 @@ def rmtree(path): + if 'E' in value: # Everything else + rmtree(THUMB_DIR) + rmtree(USER_CSS) +- rmtree(ENV_DIR) + rmtree(os.path.join(HOME_DIR, "maps")) + for fil in glob(os.path.join(HOME_DIR, "*")): + if os.path.isfile(fil): +diff --git a/gramps/gen/const.py b/gramps/gen/const.py +index 81908bf144..ee923210fe 100644 +--- a/gramps/gen/const.py ++++ b/gramps/gen/const.py +@@ -121,14 +121,13 @@ + TOOL_OPTIONS = os.path.join(HOME_DIR, "tool_options.xml") + PLACE_FORMATS = os.path.join(HOME_DIR, "place_formats.xml") + +-ENV_DIR = os.path.join(HOME_DIR, "env") + TEMP_DIR = os.path.join(HOME_DIR, "temp") + THUMB_DIR = os.path.join(HOME_DIR, "thumb") + THUMB_NORMAL = os.path.join(THUMB_DIR, "normal") + THUMB_LARGE = os.path.join(THUMB_DIR, "large") + USER_PLUGINS = os.path.join(VERSION_DIR, "plugins") + USER_CSS = os.path.join(HOME_DIR, "css") + # dirs checked/made for each Gramps session +-USER_DIRLIST = (USER_HOME, HOME_DIR, VERSION_DIR, ENV_DIR, TEMP_DIR, THUMB_DIR, ++USER_DIRLIST = (USER_HOME, HOME_DIR, VERSION_DIR, TEMP_DIR, THUMB_DIR, + THUMB_NORMAL, THUMB_LARGE, USER_PLUGINS, USER_CSS) + + +From d3a38ead9dd6384873b84a8c38ca87228ca5eae6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= +Date: Tue, 8 Mar 2022 21:54:10 +0100 +Subject: [PATCH 2/4] Geography: Use path from constants + +--- + gramps/plugins/lib/maps/geography.py | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/gramps/plugins/lib/maps/geography.py b/gramps/plugins/lib/maps/geography.py +index 9ac4e0afce..d7aa1cd514 100644 +--- a/gramps/plugins/lib/maps/geography.py ++++ b/gramps/plugins/lib/maps/geography.py +@@ -83,5 +83,4 @@ + # + # ------------------------------------------------------------------------- +-GEOGRAPHY_PATH = os.path.join(HOME_DIR, "maps") + + # ------------------------------------------------------------------------- + # +@@ -116,7 +115,7 @@ class GeoGraphyView(OsmGps, NavigationView): + """ + # settings in the config file + CONFIGSETTINGS = ( +- ('geography.path', GEOGRAPHY_PATH), ++ ('geography.path', constants.GEOGRAPHY_PATH), + + ('geography.zoom', 10), + ('geography.zoom_when_center', 12), +@@ -147,4 +146,4 @@ def __init__(self, title, pdata, dbstate, uistate, + self.lock = config.get("geography.lock") + if config.get('geography.path') == "": +- config.set('geography.path', GEOGRAPHY_PATH) ++ config.set('geography.path', constants.GEOGRAPHY_PATH) + +From ce6aa76a45e2c4868a08a430c73d1a96082d90b8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= +Date: Wed, 9 Mar 2022 19:31:00 +0100 +Subject: [PATCH 3/4] Test: Use temporary directory to test bsddb + +--- + test/LosHawlos_bsddb_test.py | 79 ++++++++++++++++-------------------- + 1 file changed, 36 insertions(+), 43 deletions(-) + +diff --git a/test/LosHawlos_bsddb_test.py b/test/LosHawlos_bsddb_test.py +index 6d2c91f7a1..2576283299 100644 +--- a/test/LosHawlos_bsddb_test.py ++++ b/test/LosHawlos_bsddb_test.py +@@ -20,48 +20,41 @@ + + # test/LosHawlos_bsddbtest.py + +-from bsddb3 import dbshelve, db +-import os +-import sys +- +-sys.path.append('../gramps') +-import gramps.gen.const as const ++import tempfile ++from bsddb3 import db + + print("Test that db.DBEnv().open() works") +-env_name = os.path.expanduser(os.path.join(const.HOME_DIR, "test")) +-if not os.path.isdir(env_name): +- os.mkdir(env_name) +- +-env = db.DBEnv() +-env.set_cachesize(0,0x2000000) +-env.set_lk_max_locks(25000) +-env.set_lk_max_objects(25000) +-# env.set_flags(db.DB_LOG_AUTOREMOVE,1) +-""" +-BSDDB change log settings using new method with renamed attributes +-""" +-autoremove_flag = None +-autoremove_method = None +-for flag in ["DB_LOG_AUTO_REMOVE", "DB_LOG_AUTOREMOVE"]: +- if hasattr(db, flag): +- autoremove_flag = getattr(db, flag) +- break +-for method in ["log_set_config", "set_flags"]: +- if hasattr(env, method): +- autoremove_method = getattr(env, method) +- break +-if autoremove_method and autoremove_flag: +- autoremove_method(autoremove_flag, 1) +-else: +- print("Failed to set autoremove flag") +-env_flags = db.DB_CREATE|db.DB_RECOVER|db.DB_PRIVATE|\ +- db.DB_INIT_MPOOL|db.DB_INIT_LOCK|\ +- db.DB_INIT_LOG|db.DB_INIT_TXN|db.DB_THREAD +-try: +- env.open(env_name,env_flags) +-except db.DBRunRecoveryError as e: +- print("Exception: ") +- print(e) +- env.remove(env_name) +- env.open(env_name,env_flags) +-print("OK") ++with tempfile.TemporaryDirectory() as env_name: ++ env = db.DBEnv() ++ env.set_cachesize(0,0x2000000) ++ env.set_lk_max_locks(25000) ++ env.set_lk_max_objects(25000) ++ # env.set_flags(db.DB_LOG_AUTOREMOVE,1) ++ """ ++ BSDDB change log settings using new method with renamed attributes ++ """ ++ autoremove_flag = None ++ autoremove_method = None ++ for flag in ["DB_LOG_AUTO_REMOVE", "DB_LOG_AUTOREMOVE"]: ++ if hasattr(db, flag): ++ autoremove_flag = getattr(db, flag) ++ break ++ for method in ["log_set_config", "set_flags"]: ++ if hasattr(env, method): ++ autoremove_method = getattr(env, method) ++ break ++ if autoremove_method and autoremove_flag: ++ autoremove_method(autoremove_flag, 1) ++ else: ++ print("Failed to set autoremove flag") ++ env_flags = db.DB_CREATE|db.DB_RECOVER|db.DB_PRIVATE|\ ++ db.DB_INIT_MPOOL|db.DB_INIT_LOCK|\ ++ db.DB_INIT_LOG|db.DB_INIT_TXN|db.DB_THREAD ++ try: ++ env.open(env_name,env_flags) ++ except db.DBRunRecoveryError as e: ++ print("Exception: ") ++ print(e) ++ env.remove(env_name) ++ env.open(env_name,env_flags) ++ print("OK") + +From 182e5aaea5d26aaed43943aec4a72c6a6410b512 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= +Date: Wed, 16 Mar 2022 20:40:16 +0100 +Subject: [PATCH 4/4] Support XDG base directory specification + +Fixes #8025 +--- + gramps/cli/argparser.py | 13 ++++++---- + gramps/gen/config.py | 8 +++--- + gramps/gen/const.py | 39 ++++++++++++++++++++-------- + gramps/gen/plug/report/_book.py | 4 +-- + gramps/gen/plug/report/_options.py | 4 +-- + gramps/gen/recentfiles.py | 4 +-- + gramps/grampsapp.py | 10 +++---- + gramps/gui/configure.py | 4 +-- + gramps/gui/viewmanager.py | 4 +-- + gramps/plugins/lib/maps/constants.py | 4 +-- + gramps/plugins/lib/maps/geography.py | 6 ++--- + gramps/plugins/tool/verify.py | 4 +-- + gramps/plugins/webstuff/webstuff.py | 6 ++--- + 13 files changed, 65 insertions(+), 45 deletions(-) + +diff --git a/gramps/cli/argparser.py b/gramps/cli/argparser.py +index e13bbd4ec3..7ca738ab9d 100644 +--- a/gramps/cli/argparser.py ++++ b/gramps/cli/argparser.py +@@ -48,7 +48,8 @@ + # + #------------------------------------------------------------------------- + from gramps.gen.const import (LONGOPTS, SHORTOPTS, USER_PLUGINS, VERSION_DIR, +- HOME_DIR, TEMP_DIR, THUMB_DIR, USER_CSS) ++ USER_CACHE, USER_CONFIG, USER_DATA, THUMB_DIR, ++ USER_CSS) + from gramps.gen.utils.cast import get_type_converter + from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext +@@ -430,17 +431,19 @@ def rmtree(path): + if os.path.isfile(fil): + os.remove(fil) + if 'E' in value or 'X' in value: # clear xml reports/tools +- for fil in glob(os.path.join(HOME_DIR, "*.xml")): ++ for fil in glob(os.path.join(USER_DATA, "*.xml")): + os.remove(fil) + if 'E' in value or 'Z' in value: # clear upgrade zips +- for fil in glob(os.path.join(HOME_DIR, "*.zip")): ++ for fil in glob(os.path.join(USER_DATA, "*.zip")): + os.remove(fil) + if 'E' in value: # Everything else + rmtree(TEMP_DIR) + rmtree(THUMB_DIR) + rmtree(USER_CSS) +- rmtree(os.path.join(HOME_DIR, "maps")) +- for fil in glob(os.path.join(HOME_DIR, "*")): ++ rmtree(os.path.join(USER_CACHE, "maps")) ++ for fil in (glob(os.path.join(USER_CACHE, "*")) ++ + glob(os.path.join(USER_CONFIG, "*")) ++ + glob(os.path.join(USER_DATA, "*"))): + if os.path.isfile(fil): + os.remove(fil) + sys.exit(0) # Done with Default +diff --git a/gramps/gen/config.py b/gramps/gen/config.py +index 0e20f9712f..5dabea04c5 100644 +--- a/gramps/gen/config.py ++++ b/gramps/gen/config.py +@@ -41,7 +41,7 @@ + # Gramps imports + # + #--------------------------------------------------------------- +-from .const import HOME_DIR, USER_HOME, VERSION_DIR ++from .const import USER_CONFIG, USER_DATA, USER_HOME, VERSION_DIR + from .utils.configmanager import ConfigManager + from .const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext +@@ -163,7 +163,7 @@ def emit(key): + register('database.backup-path', USER_HOME) + register('database.backup-on-exit', True) + register('database.autobackup', 0) +-register('database.path', os.path.join(HOME_DIR, 'grampsdb')) ++register('database.path', os.path.join(USER_DATA, 'grampsdb')) + register('database.host', '') + register('database.port', '') + +@@ -338,10 +338,10 @@ def emit(key): + # we can tell by seeing if there is a key file for this version: + if not os.path.exists(CONFIGMAN.filename): + # If not, let's read old if there: +- if os.path.exists(os.path.join(HOME_DIR, "keys.ini")): ++ if os.path.exists(os.path.join(USER_CONFIG, "keys.ini")): + # read it in old style: + logging.warning("Importing old key file 'keys.ini'...") +- CONFIGMAN.load(os.path.join(HOME_DIR, "keys.ini"), ++ CONFIGMAN.load(os.path.join(USER_CONFIG, "keys.ini"), + oldstyle=True) + logging.warning("Done importing old key file 'keys.ini'") + # other version upgrades here... +diff --git a/gramps/gen/const.py b/gramps/gen/const.py +index ee923210fe..6ae13226c6 100644 +--- a/gramps/gen/const.py ++++ b/gramps/gen/const.py +@@ -34,6 +34,8 @@ + import sys + import uuid + ++from gi.repository import GLib ++ + #------------------------------------------------------------------------- + # + # Gramps modules +@@ -113,22 +115,34 @@ + HOME_DIR = get_env_var('SAFEMODE') + + +-VERSION_DIR = os.path.join( +- HOME_DIR, "gramps%s%s" % (VERSION_TUPLE[0], VERSION_TUPLE[1])) ++if (os.path.exists(HOME_DIR) or 'GRAMPSHOME' in os.environ ++ or 'SAFEMODE' in os.environ): ++ USER_DATA = HOME_DIR ++ USER_CONFIG = HOME_DIR ++ USER_CACHE = HOME_DIR ++else: ++ USER_DATA = os.path.join(GLib.get_user_data_dir(), 'gramps') ++ USER_CONFIG = os.path.join(GLib.get_user_config_dir(), 'gramps') ++ USER_CACHE = os.path.join(GLib.get_user_cache_dir(), 'gramps') ++ ++VERSION_DIR_NAME = "gramps%s%s" % (VERSION_TUPLE[0], VERSION_TUPLE[1]) ++VERSION_DIR = os.path.join(USER_CONFIG, VERSION_DIR_NAME) ++USER_DATA_VERSION = os.path.join(USER_DATA, VERSION_DIR_NAME) + + CUSTOM_FILTERS = os.path.join(VERSION_DIR, "custom_filters.xml") +-REPORT_OPTIONS = os.path.join(HOME_DIR, "report_options.xml") +-TOOL_OPTIONS = os.path.join(HOME_DIR, "tool_options.xml") +-PLACE_FORMATS = os.path.join(HOME_DIR, "place_formats.xml") ++REPORT_OPTIONS = os.path.join(USER_CONFIG, "report_options.xml") ++TOOL_OPTIONS = os.path.join(USER_CONFIG, "tool_options.xml") ++PLACE_FORMATS = os.path.join(USER_CONFIG, "place_formats.xml") + +-TEMP_DIR = os.path.join(HOME_DIR, "temp") +-THUMB_DIR = os.path.join(HOME_DIR, "thumb") ++TEMP_DIR = os.path.join(USER_CACHE, "temp") ++THUMB_DIR = os.path.join(USER_CACHE, "thumb") + THUMB_NORMAL = os.path.join(THUMB_DIR, "normal") + THUMB_LARGE = os.path.join(THUMB_DIR, "large") +-USER_PLUGINS = os.path.join(VERSION_DIR, "plugins") +-USER_CSS = os.path.join(HOME_DIR, "css") ++USER_PLUGINS = os.path.join(USER_DATA_VERSION, "plugins") ++USER_CSS = os.path.join(USER_DATA, "css") + # dirs checked/made for each Gramps session +-USER_DIRLIST = (USER_HOME, HOME_DIR, VERSION_DIR, TEMP_DIR, THUMB_DIR, +- THUMB_NORMAL, THUMB_LARGE, USER_PLUGINS, USER_CSS) ++USER_DIRLIST = (USER_HOME, USER_CACHE, USER_CONFIG, USER_DATA, VERSION_DIR, ++ USER_DATA_VERSION, THUMB_DIR, THUMB_NORMAL, ++ THUMB_LARGE, USER_PLUGINS, USER_CSS) + + + #------------------------------------------------------------------------- +@@ -206,10 +206,13 @@ + #------------------------------------------------------------------------- + ENV = { + "USER_HOME": USER_HOME, +- "HOME_DIR": HOME_DIR, ++ "USER_CACHE": USER_CACHE, ++ "USER_CONFIG": USER_CONFIG, ++ "USER_DATA": USER_DATA, + "VERSION": VERSION, + "major_version": major_version, + "VERSION_DIR": VERSION_DIR, ++ "USER_DATA_VERSION": USER_DATA_VERSION, + "THUMB_DIR": THUMB_DIR, + "THUMB_NORMAL": THUMB_NORMAL, + "THUMB_LARGE": THUMB_LARGE, +diff --git a/gramps/gen/plug/report/_book.py b/gramps/gen/plug/report/_book.py +index 24d560e62c..be92ccf604 100644 +--- a/gramps/gen/plug/report/_book.py ++++ b/gramps/gen/plug/report/_book.py +@@ -57,7 +57,7 @@ + #------------------------------------------------------------------------- + from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext +-from ...const import HOME_DIR ++from ...const import USER_DATA + from ...utils.cast import get_type_converter_by_name, type_name + from ..docgen import StyleSheet, StyleSheetList + from .. import BasePluginManager +@@ -433,7 +433,7 @@ def __init__(self, filename, dbase): + self.dbase = dbase + self.bookmap = {} + self._needs_saving = None +- self.file = os.path.join(HOME_DIR, filename) ++ self.file = os.path.join(USER_DATA, filename) + self.parse() + + def delete_book(self, name): +diff --git a/gramps/gen/plug/report/_options.py b/gramps/gen/plug/report/_options.py +index d29ccb4c96..92df8c96b8 100644 +--- a/gramps/gen/plug/report/_options.py ++++ b/gramps/gen/plug/report/_options.py +@@ -59,7 +59,7 @@ + # (do not import anything from 'gui' as this is in 'gen') + # + #------------------------------------------------------------------------- +-from ...const import HOME_DIR, REPORT_OPTIONS ++from ...const import USER_DATA, REPORT_OPTIONS + from ...config import config + from ..docgen import PAPER_PORTRAIT + from .. import _options +@@ -739,7 +739,7 @@ def get_stylesheet_savefile(self): + # Get the first part of name, if it contains a comma: + # (will just be module_name, if no comma) + filename = "%s.xml" % self.module_name.split(",")[0] +- return os.path.join(HOME_DIR, filename) ++ return os.path.join(USER_DATA, filename) + + def get_default_stylesheet_name(self): + """ get the default stylesheet name """ +diff --git a/gramps/gen/recentfiles.py b/gramps/gen/recentfiles.py +index 900b4b0d94..3ce32f2b95 100644 +--- a/gramps/gen/recentfiles.py ++++ b/gramps/gen/recentfiles.py +@@ -37,7 +37,7 @@ + except ImportError: + USE_LOCK = False + +-from .const import HOME_DIR, GRAMPS_LOCALE as glocale ++from .const import USER_DATA, GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext + + #------------------------------------------------------------------------- +@@ -45,7 +45,7 @@ + # Constants + # + #------------------------------------------------------------------------- +-GRAMPS_FILENAME = os.path.join(HOME_DIR, "recent-files-gramps.xml") ++GRAMPS_FILENAME = os.path.join(USER_DATA, "recent-files-gramps.xml") + MAX_GRAMPS_ITEMS = 10 + + #------------------------------------------------------------------------- +diff --git a/gramps/grampsapp.py b/gramps/grampsapp.py +index bc0f36ae94..cf8774df9b 100644 +--- a/gramps/grampsapp.py ++++ b/gramps/grampsapp.py +@@ -50,7 +50,7 @@ + # Gramps modules + # + #------------------------------------------------------------------------- +-from .gen.const import APP_GRAMPS, USER_DIRLIST, HOME_DIR, ORIG_HOME_DIR ++from .gen.const import APP_GRAMPS, USER_DIRLIST, USER_DATA, ORIG_HOME_DIR + from .gen.constfunc import mac + from .version import VERSION_TUPLE + from .gen.constfunc import win, get_env_var +@@ -113,7 +113,7 @@ + if win(): + # If running in GUI mode redirect stdout and stderr to log file + if not sys.stdout: +- logfile = os.path.join(HOME_DIR, ++ logfile = os.path.join(USER_DATA, + "Gramps%s%s.log") % (VERSION_TUPLE[0], + VERSION_TUPLE[1]) + # We now carry out the first step in build_user_paths(), to make sure +@@ -122,10 +122,10 @@ + # block, and any failure will be logged. However, if the creation of the + # user directory fails here, there is no way to report the failure, + # because stdout/stderr are not available, and neither is the logfile. +- if os.path.islink(HOME_DIR): ++ if os.path.islink(USER_DATA): + pass # ok +- elif not os.path.isdir(HOME_DIR): +- os.makedirs(HOME_DIR) ++ elif not os.path.isdir(USER_DATA): ++ os.makedirs(USER_DATA) + sys.stdout = sys.stderr = open(logfile, "w", encoding='utf-8') + # macOS sets stderr to /dev/null when running without a terminal, + # e.g. if Gramps.app is lauched by double-clicking on it in +diff --git a/gramps/gui/configure.py b/gramps/gui/configure.py +index debbc73ae7..1747b7c529 100644 +--- a/gramps/gui/configure.py ++++ b/gramps/gui/configure.py +@@ -50,7 +50,7 @@ + #------------------------------------------------------------------------- + from gramps.gen.config import config + from gramps.gen.const import GRAMPS_LOCALE as glocale +-from gramps.gen.const import HOME_DIR, URL_WIKISTRING, URL_MANUAL_PAGE ++from gramps.gen.const import USER_DATA, URL_WIKISTRING, URL_MANUAL_PAGE + from gramps.gen.datehandler import get_date_formats + from gramps.gen.display.name import displayer as _nd + from gramps.gen.display.name import NameDisplayError +@@ -1997,7 +1997,7 @@ def select_dbpath(self, *obj): + _('_Apply'), Gtk.ResponseType.OK) + dbpath = config.get('database.path') + if not dbpath: +- dbpath = os.path.join(HOME_DIR, 'grampsdb') ++ dbpath = os.path.join(USER_DATA, 'grampsdb') + f.set_current_folder(os.path.dirname(dbpath)) + + status = f.run() +diff --git a/gramps/gui/viewmanager.py b/gramps/gui/viewmanager.py +index 2189899757..9e27c10f45 100644 +--- a/gramps/gui/viewmanager.py ++++ b/gramps/gui/viewmanager.py +@@ -77,7 +77,7 @@ + from .pluginmanager import GuiPluginManager + from gramps.gen.relationship import get_relationship_calculator + from .displaystate import DisplayState, RecentDocsMenu +-from gramps.gen.const import (HOME_DIR, ICON, URL_BUGTRACKER, URL_HOMEPAGE, ++from gramps.gen.const import (USER_DATA, ICON, URL_BUGTRACKER, URL_HOMEPAGE, + URL_MAILINGLIST, URL_MANUAL_PAGE, URL_WIKISTRING, + WIKI_EXTRAPLUGINS, URL_BUGHOME) + from gramps.gen.constfunc import is_quartz +@@ -1787,7 +1787,7 @@ def select_backup_path(self, widget, path_entry): + _('_Apply'), Gtk.ResponseType.OK) + mpath = path_entry.get_text() + if not mpath: +- mpath = HOME_DIR ++ mpath = USER_DATA + fdialog.set_current_folder(os.path.dirname(mpath)) + fdialog.set_filename(os.path.join(mpath, ".")) + status = fdialog.run() +diff --git a/gramps/plugins/lib/maps/constants.py b/gramps/plugins/lib/maps/constants.py +index b868ea4332..8a3df43a4c 100644 +--- a/gramps/plugins/lib/maps/constants.py ++++ b/gramps/plugins/lib/maps/constants.py +@@ -29,7 +29,7 @@ + from gramps.gen.lib import EventType + import os +-from gramps.gen.const import HOME_DIR ++from gramps.gen.const import USER_CACHE + import gi + gi.require_version('OsmGpsMap', '1.0') + from gi.repository import OsmGpsMap as osmgpsmap + +@@ -38,7 +38,7 @@ + # Constants + # + #------------------------------------------------------------------------- +-GEOGRAPHY_PATH = os.path.join(HOME_DIR, "maps") ++GEOGRAPHY_PATH = os.path.join(USER_CACHE, "maps") + + ICONS = { + EventType.BIRTH : 'gramps-geo-birth', +diff --git a/gramps/plugins/lib/maps/geography.py b/gramps/plugins/lib/maps/geography.py +index d7aa1cd514..97f6370f6b 100644 +--- a/gramps/plugins/lib/maps/geography.py ++++ b/gramps/plugins/lib/maps/geography.py +@@ -55,7 +55,7 @@ + from gramps.gui.views.navigationview import NavigationView + from gramps.gen.utils.libformatting import FormattingHelper + from gramps.gen.errors import WindowActiveError +-from gramps.gen.const import HOME_DIR ++from gramps.gen.const import USER_HOME + from gramps.gen.config import config + from gramps.gui.editors import EditPlace, EditEvent, EditFamily, EditPerson + from gramps.gui.selectors.selectplace import SelectPlace +@@ -991,7 +991,7 @@ def add_place_from_kml(self, menu, event, lat, lon): + parent=self.uistate.window, + buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL, + _('_Apply'), Gtk.ResponseType.OK)) +- mpath = HOME_DIR ++ mpath = USER_HOME + kml.set_current_folder(os.path.dirname(mpath)) + kml.set_filter(filtering) + +@@ -1292,7 +1292,7 @@ def select_tilepath(self, *obj): + Gtk.ResponseType.OK)) + mpath = config.get('geography.path') + if not mpath: +- mpath = HOME_DIR ++ mpath = USER_HOME + selected_dir.set_current_folder(os.path.dirname(mpath)) + + status = selected_dir.run() +diff --git a/gramps/plugins/tool/verify.py b/gramps/plugins/tool/verify.py +index 6d989c9b08..adcea2bf23 100644 +--- a/gramps/plugins/tool/verify.py ++++ b/gramps/plugins/tool/verify.py +@@ -62,7 +62,7 @@ + from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext + from gramps.gen.errors import WindowActiveError +-from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR ++from gramps.gen.const import URL_MANUAL_PAGE, USER_DATA_VERSION + from gramps.gen.lib import (ChildRefType, EventRoleType, EventType, + FamilyRelType, NameType, Person) + from gramps.gen.lib.date import Today +@@ -595,7 +595,7 @@ def _set_filename(self): + db_filename = db_filename.encode('utf-8') + md5sum = md5(db_filename) + self.ignores_filename = os.path.join( +- VERSION_DIR, md5sum.hexdigest() + os.path.extsep + 'vfm') ++ USER_DATA_VERSION, md5sum.hexdigest() + os.path.extsep + 'vfm') + + def load_ignored(self, db_filename): + """ get ready to load the file with the previously-ignored people """ +diff --git a/gramps/plugins/webstuff/webstuff.py b/gramps/plugins/webstuff/webstuff.py +index eaacb58202..6c531be5e5 100644 +--- a/gramps/plugins/webstuff/webstuff.py ++++ b/gramps/plugins/webstuff/webstuff.py +@@ -23,7 +23,7 @@ + # python modules + #------------------------------------------------ + import os +-from gramps.gen.const import VERSION_DIR, IMAGE_DIR, DATA_DIR, USER_CSS ++from gramps.gen.const import USER_DATA_VERSION, IMAGE_DIR, DATA_DIR, USER_CSS + from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext + +@@ -186,10 +186,10 @@ def process_list(data): + file = row[3] + if file: + path, filename = os.path.split(file) +- # is there a override file in the VERSION_DIR/webstuff? ++ # is there a override file in the DATA_VERSION_DIR/webstuff? + # eg, ~/.gramps/gramps34/webstuff/Web_Nebraska.css + # if so, replace this one: +- override = os.path.join(VERSION_DIR, "webstuff", filename) ++ override = os.path.join(USER_DATA_VERSION, "webstuff", filename) + if os.path.exists(override): + row[3] = override + retval.append(row) + +From b554ba7d23e1b5146f3babc5bb326d0c1a3d1c00 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= +Date: Tue, 8 Mar 2022 21:52:49 +0100 +Subject: [PATCH 1/4] Remove unused constant ENV_DIR + +--- + gramps/cli/argparser.py | 3 +-- + gramps/gen/const.py | 4 +--- + 2 files changed, 2 insertions(+), 5 deletions(-) + +diff --git a/gramps/gen/const.py b/gramps/gen/const.py +index 81908bf144..ee923210fe 100644 +--- a/gramps/gen/const.py ++++ b/gramps/gen/const.py +@@ -197,7 +197,6 @@ + "VERSION": VERSION, + "major_version": major_version, + "VERSION_DIR": VERSION_DIR, +- "ENV_DIR": ENV_DIR, + "TEMP_DIR": TEMP_DIR, + "THUMB_DIR": THUMB_DIR, + "THUMB_NORMAL": THUMB_NORMAL, + "THUMB_LARGE": THUMB_LARGE, diff --git a/os/etc/portage/patches/app-misc/lfm/0001-enable-shared-linking.patch b/os/etc/portage/patches/app-misc/lfm/0001-enable-shared-linking.patch new file mode 100644 index 0000000..a38731b --- /dev/null +++ b/os/etc/portage/patches/app-misc/lfm/0001-enable-shared-linking.patch @@ -0,0 +1,96 @@ +From bd24edd233ab7925bc75ad2f44cf58479d89cfec Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Wed, 12 Jul 2023 19:35:18 +0900 +Subject: [PATCH 1/2] enable shared linking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + CMakeLists.txt | 46 +++++++++++++++++++-------------------- + cmake/FindNotcurses.cmake | 4 ++-- + 2 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b3efcbc..d010e75 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -29,28 +29,28 @@ set(DEPS_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/.deps/usr") + list(INSERT CMAKE_PREFIX_PATH 0 ${DEPS_PREFIX}) + set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${DEPS_PREFIX}/lib/pkgconfig") + +-if(NOT EXISTS ${DEPS_PREFIX}) +- message(STATUS "Building dependencies...") +- set(DEPS_BUILD_DIR ${PROJECT_SOURCE_DIR}/.deps) +- file(MAKE_DIRECTORY ${DEPS_BUILD_DIR}) +- execute_process( +- COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} +- -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} +- -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} +- -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} +- -DCMAKE_C_FLAGS=${CMAKE_C_FLGS} +- -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} +- -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL} +- -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} +- -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} +- -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} +- ${PROJECT_SOURCE_DIR}/third-party +- WORKING_DIRECTORY ${DEPS_BUILD_DIR}) +- execute_process( +- COMMAND ${CMAKE_COMMAND} --build ${DEPS_BUILD_DIR} +- --config ${CMAKE_BUILD_TYPE}) +- set(DEPS_PREFIX ${DEPS_BUILD_DIR}/usr) +-endif() ++# if(NOT EXISTS ${DEPS_PREFIX}) ++# message(STATUS "Building dependencies...") ++# set(DEPS_BUILD_DIR ${PROJECT_SOURCE_DIR}/.deps) ++# file(MAKE_DIRECTORY ${DEPS_BUILD_DIR}) ++# execute_process( ++# COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} ++# -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} ++# -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ++# -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} ++# -DCMAKE_C_FLAGS=${CMAKE_C_FLGS} ++# -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} ++# -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL} ++# -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} ++# -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} ++# -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} ++# ${PROJECT_SOURCE_DIR}/third-party ++# WORKING_DIRECTORY ${DEPS_BUILD_DIR}) ++# execute_process( ++# COMMAND ${CMAKE_COMMAND} --build ${DEPS_BUILD_DIR} ++# --config ${CMAKE_BUILD_TYPE}) ++# set(DEPS_PREFIX ${DEPS_BUILD_DIR}/usr) ++# endif() + option(DEV "dev" OFF) + + set(LUA_PRG luajit) +@@ -161,7 +161,7 @@ find_package(Pcre REQUIRED) + find_package(ZLIB REQUIRED) + find_package(Ev REQUIRED) + find_package(FFmpeg REQUIRED COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE) +-set(NOTCURSES_DEPS m unistring ncursesw readline deflate) ++# set(NOTCURSES_DEPS m unistring ncursesw readline deflate) + + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads REQUIRED) +diff --git a/cmake/FindNotcurses.cmake b/cmake/FindNotcurses.cmake +index 4aa9bca..a50f32b 100644 +--- a/cmake/FindNotcurses.cmake ++++ b/cmake/FindNotcurses.cmake +@@ -13,8 +13,8 @@ set(NOTCURSES_DEFINITIONS ${PC_NOTCURSES_CFLAGS_OTHER}) + find_path(NOTCURSES_INCLUDE_DIR notcurses/notcurses.h + PATHS ${PC_NOTCURSES_INCLUDEDIR} ${PC_NOTCURSES_INCLUDE_DIRS}) + +-list(APPEND NOTCURSES_NAMES libnotcurses.a) +-list(APPEND NOTCURSES_CORE_NAMES libnotcurses-core.a) ++list(APPEND NOTCURSES_NAMES libnotcurses.a libnotcurses.so) ++list(APPEND NOTCURSES_CORE_NAMES libnotcurses-core.a libnotcurses-core.so) + + find_library(NOTCURSES_LIBRARY NAMES ${NOTCURSES_NAMES} + PATHS ${PC_NOTCURSES_LIBDIR} ${PC_NOTCURSES_LIBRARY_DIRS}) +-- +2.39.3 + diff --git a/os/etc/portage/patches/app-misc/lfm/0002-fix-inline-usage.patch b/os/etc/portage/patches/app-misc/lfm/0002-fix-inline-usage.patch new file mode 100644 index 0000000..4f5b2fc --- /dev/null +++ b/os/etc/portage/patches/app-misc/lfm/0002-fix-inline-usage.patch @@ -0,0 +1,29 @@ +From 8692ed3436709038bec7bed30476886be48cb86e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Wed, 12 Jul 2023 19:38:41 +0900 +Subject: [PATCH 2/2] fix inline usage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + src/dir.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/dir.h b/src/dir.h +index e38c20e..f5df11d 100644 +--- a/src/dir.h ++++ b/src/dir.h +@@ -100,7 +100,7 @@ void dir_cursor_move_to(Dir *dir, const char *name, uint32_t height, uint32_t sc + void dir_update_with(Dir *dir, Dir *update, uint32_t height, uint32_t scrolloff); + + // Returns true `d` is the root directory. +-inline bool dir_isroot(const Dir *dir) ++static inline bool dir_isroot(const Dir *dir) + { + return (dir->path[0] == '/' && dir->path[1] == 0); + } +-- +2.39.3 + diff --git a/os/etc/portage/patches/app-misc/todoman/0001-add-relation-to-cache-and-model.patch b/os/etc/portage/patches/app-misc/todoman/0001-add-relation-to-cache-and-model.patch new file mode 100644 index 0000000..4083d69 --- /dev/null +++ b/os/etc/portage/patches/app-misc/todoman/0001-add-relation-to-cache-and-model.patch @@ -0,0 +1,242 @@ +From f57cccf23b093f33c0096006ce4ae0b823807121 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Tue, 17 Jan 2023 21:58:16 +0100 +Subject: [PATCH 1/4] add relation to cache and model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + tests/test_model.py | 33 +++++++++++++++++++ + todoman/model.py | 78 +++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 105 insertions(+), 6 deletions(-) + +diff --git a/tests/test_model.py b/tests/test_model.py +index 363d468..0ff5d86 100644 +--- a/tests/test_model.py ++++ b/tests/test_model.py +@@ -421,6 +421,38 @@ def test_illegal_start_suppression(create, default_database, todos): + assert todo.due == datetime(2017, 3, 31, 12, tzinfo=tzoffset(None, 7200)) + + ++def test_relation(create, todos): ++ create( ++ "test_parent.ics", ++ "UID:9999\n" ++ "SUMMARY:Start doing stuff\n" ++ "DUE;VALUE=DATE-TIME;TZID=CET:20170331T120000\n" ++ ) ++ parent = next(todos()) ++ ++ create( ++ "test_child_1.ics", ++ "UID:9998\n" ++ "SUMMARY:this is part a\n" ++ "DUE;VALUE=DATE-TIME;TZID=CET:20170331T120000\n" ++ f"RELATED-TO:{parent.uid}\n" ++ ) ++ child1 = next(todos()) ++ ++ create( ++ "test_child_2.ics", ++ "UID:9997\n" ++ "SUMMARY:this is part b\n" ++ "DUE;VALUE=DATE-TIME;TZID=CET:20170331T120000\n" ++ f"RELATED-TO;RELTYPE=PARENT:{parent.uid}\n" ++ ) ++ child2 = next(todos()) ++ ++ assert child1.relation == ("PARENT", parent.uid) ++ assert child2.relation == ("PARENT", parent.uid) ++ assert not parent.relation ++ ++ + def test_default_status(create, todos): + create("test.ics", "SUMMARY:Finish all these status tests\n") + todo = next(todos()) +@@ -539,3 +571,4 @@ def test_todo_path_without_list(tmpdir): + + with pytest.raises(ValueError, match="A todo without a list does not have a path."): + todo.path # noqa: B018 # expression raises ++ +diff --git a/todoman/model.py b/todoman/model.py +index bb4044a..970a4b7 100644 +--- a/todoman/model.py ++++ b/todoman/model.py +@@ -49,6 +49,7 @@ class Todo: + dtstamp: datetime | None + last_modified: datetime | None + related: list[Todo] ++ relation: list[tuple[str, str]] + rrule: str | None + start: date | None + +@@ -98,6 +99,7 @@ class Todo: + + self.filename = filename or f"{self.uid}.ics" + self.related = [] ++ self.relation = None + + if os.path.basename(self.filename) != self.filename: + raise ValueError(f"Must not be an absolute path: {self.filename}") +@@ -402,7 +404,7 @@ class Cache: + may be used for filtering/sorting. + """ + +- SCHEMA_VERSION = 9 ++ SCHEMA_VERSION = 10 + + def __init__(self, path: str): + self.cache_path = str(path) +@@ -434,6 +436,7 @@ class Cache: + DROP TABLE IF EXISTS lists; + DROP TABLE IF EXISTS files; + DROP TABLE IF EXISTS categories; ++ DROP TABLE IF EXISTS relations; + """ + ) + +@@ -489,6 +492,18 @@ class Cache: + """ + ) + ++ self._conn.execute( ++ """ ++ CREATE TABLE IF NOT EXISTS relations ( ++ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ++ "todos_id" INTEGER NOT NULL, ++ "reltype" TEXT, ++ "related_uid" TEXT, ++ ++ FOREIGN KEY(todos_id) REFERENCES todos(id) ON DELETE CASCADE ++ ); ++ """ ++ ) + self._conn.execute( + """ + CREATE TABLE IF NOT EXISTS todos ( +@@ -593,6 +608,21 @@ class Cache: + except sqlite3.IntegrityError as e: + raise exceptions.AlreadyExistsError("category", category) from e + ++ def add_relation(self, todos_id, relation): ++ try: ++ self._conn.execute( ++ """ ++ INSERT INTO relations ( ++ todos_id, ++ reltype, ++ related_uid ++ ) VALUES (?, ?, ?); ++ """, ++ (todos_id, relation[0], relation[1]), ++ ) ++ except sqlite3.IntegrityError as e: ++ raise exceptions.AlreadyExists("relation", relation) from e ++ + def _serialize_datetime( + self, + todo: icalendar.Todo, +@@ -625,6 +655,19 @@ class Cache: + + return rrule.to_ical().decode() + ++ def _serialize_relation( ++ self, ++ todo: icalendar.Todo, ++ ) -> str | None: ++ ++ for cl in todo.content_lines(): ++ if type(cl) != str: ++ parts = cl.parts() ++ if parts[0] == "RELATED-TO": ++ return ((parts[1].has_key("RELTYPE") and parts[1].get("RELTYPE")) or "PARENT", parts[2]) ++ ++ return None ++ + def add_vtodo(self, todo: icalendar.Todo, file_path: str, id=None) -> int: + """ + Adds a todo into the cache. +@@ -702,6 +745,10 @@ class Cache: + for category in todo.get("categories").cats: + self.add_category(rv, category) + ++ rel = self._serialize_relation(todo) ++ if rel: ++ self.add_relation(rv, rel) ++ + return rv + + def todos( +@@ -825,10 +872,14 @@ class Cache: + + query = """ + SELECT DISTINCT todos.*, files.list_name, files.path, +- group_concat(category) AS categories ++ group_concat(category) AS categories, ++ group_concat(relations.reltype) AS reltype, ++ group_concat(relations.related_uid) AS related_uid + FROM todos, files + LEFT JOIN categories +- ON categories.todos_id = todos.id ++ ON categories.todos_id = todos.id ++ LEFT JOIN relations ++ ON relations.todos_id = todos.id + WHERE todos.file_path = files.path {} + GROUP BY uid + ORDER BY {} +@@ -840,7 +891,10 @@ class Cache: + logger.debug(query) + logger.debug(params) + +- result = self._conn.execute(query, params) ++ try: ++ result = self._conn.execute(query, params) ++ except Exception as e: ++ print("!", e) + + seen_paths = set() + warned_paths = set() +@@ -879,6 +933,12 @@ class Cache: + + return [] + ++ def _relation_from_db(self, reltype, uid): ++ if (not reltype) and (not uid): ++ return None ++ ++ return (reltype, uid) ++ + def _todo_from_db(self, row: dict) -> Todo: + todo = Todo() + todo.id = row["id"] +@@ -902,6 +962,8 @@ class Cache: + todo.list = self.lists_map[row["list_name"]] + todo.filename = os.path.basename(row["path"]) + todo.rrule = row["rrule"] ++ todo.relation = self._relation_from_db(row["reltype"], row["related_uid"]) ++ + return todo + + def lists(self) -> Iterable[TodoList]: +@@ -935,10 +997,14 @@ class Cache: + result = self._conn.execute( + """ + SELECT todos.*, files.list_name, files.path, +- group_concat(category) AS categories ++ group_concat(category) AS categories, ++ group_concat(relations.reltype) AS reltype, ++ group_concat(relations.related_uid) AS related_uid + FROM todos, files + LEFT JOIN categories +- ON categories.todos_id = todos.id ++ ON categories.todos_id = todos.id ++ LEFT JOIN relations ++ ON relations.todos_id = todos.id + WHERE files.path = todos.file_path + AND todos.id = ? + GROUP BY uid +-- +2.39.3 + diff --git a/os/etc/portage/patches/app-misc/todoman/0002-allow-printing-the-raw-vtodo-card.patch b/os/etc/portage/patches/app-misc/todoman/0002-allow-printing-the-raw-vtodo-card.patch new file mode 100644 index 0000000..d94037c --- /dev/null +++ b/os/etc/portage/patches/app-misc/todoman/0002-allow-printing-the-raw-vtodo-card.patch @@ -0,0 +1,50 @@ +From df131b270f677cdef74b00c6ca94c04f99530802 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Tue, 17 Jan 2023 21:58:35 +0100 +Subject: [PATCH 2/4] allow printing the raw vtodo card +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + todoman/cli.py | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/todoman/cli.py b/todoman/cli.py +index 5abb2d5..db3facc 100644 +--- a/todoman/cli.py ++++ b/todoman/cli.py +@@ -440,14 +440,28 @@ def edit(ctx, id, todo_properties, interactive, raw): + + + @cli.command() ++@click.option( ++ "--raw", ++ is_flag=True, ++ help="Show VTODO asscociated with the task.", ++) + @pass_ctx + @with_id_arg + @catch_errors +-def show(ctx, id): ++def show(ctx, id, raw): + """ + Show details about a task. + """ + todo = ctx.db.todo(id, read_only=True) ++ if raw: ++ click.echo(f"path: {todo.path}") ++ try: ++ with open(todo.path, "rb") as f: ++ click.echo(f.read()) ++ f.close() ++ except Exception: ++ logger.exception("Failed to read entry %s.", todo.path) ++ return + click.echo(ctx.formatter.detailed(todo)) + + +-- +2.39.3 + diff --git a/os/etc/portage/patches/app-misc/todoman/0003-format-list-with-hierarchy.patch b/os/etc/portage/patches/app-misc/todoman/0003-format-list-with-hierarchy.patch new file mode 100644 index 0000000..b2db1a3 --- /dev/null +++ b/os/etc/portage/patches/app-misc/todoman/0003-format-list-with-hierarchy.patch @@ -0,0 +1,126 @@ +From 054c76bcb81b94823439954fdee363bdd08011f5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Tue, 17 Jan 2023 22:19:34 +0100 +Subject: [PATCH 3/4] format list with hierarchy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + tests/test_porcelain.py | 5 +++++ + todoman/formatters.py | 29 +++++++++++++++++++++++++++-- + 2 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/tests/test_porcelain.py b/tests/test_porcelain.py +index 781891d..bc2deaa 100644 +--- a/tests/test_porcelain.py ++++ b/tests/test_porcelain.py +@@ -66,6 +66,7 @@ def test_list_start_date(tmpdir, runner, create): + "percent": 26, + "priority": 0, + "start": 1451692800, ++ "relation": None, + "summary": "Do stuff", + } + ] +@@ -98,6 +99,7 @@ def test_list_due_date(tmpdir, runner, create): + "percent": 26, + "priority": 0, + "start": None, ++ "relation": None, + "summary": "Do stuff", + } + ] +@@ -126,6 +128,7 @@ def test_list_nodue(tmpdir, runner, create): + "percent": 12, + "priority": 4, + "start": None, ++ "relation": None, + "summary": "Do stuff", + } + ] +@@ -195,6 +198,7 @@ def test_show(tmpdir, runner, create): + "percent": 0, + "priority": 5, + "start": None, ++ "relation": None, + "summary": "harhar", + } + +@@ -218,6 +222,7 @@ def test_simple_action(todo_factory): + "percent": 0, + "priority": 0, + "start": None, ++ "relation": None, + "summary": "YARR!", + } + +diff --git a/todoman/formatters.py b/todoman/formatters.py +index 4ec8425..cd801bc 100644 +--- a/todoman/formatters.py ++++ b/todoman/formatters.py +@@ -66,6 +66,7 @@ class DefaultFormatter: + # it can end up being more readable when too many columns are empty. + # show dates that are in the future in yellow (in 24hs) or grey (future) + table = [] ++ children: Dict[List[str]] = dict() + for todo in todos: + completed = "X" if todo.is_completed else " " + percent = todo.percent_complete or "" +@@ -108,12 +109,34 @@ class DefaultFormatter: + + # FIXME: double space when no priority + # split into parts to satisfy linter line too long +- table.append( ++ entry = ( + f"[{completed}] {todo.id} {priority} {due} " + f"{recurring}{summary}{categories}" + ) + +- return "\n".join(table) ++ if todo.relation and todo.relation[0] == "PARENT": ++ uid = todo.relation[1] ++ if not uid in children.keys(): ++ children[uid] = [entry] ++ else: ++ children[uid].append(entry) ++ else: ++ table.append((todo.uid, entry)) ++ ++ output = "" ++ for uid, todo in table: ++ delim = "" ++ if output != "": ++ delim = "\n" ++ output = f"{output}{delim}{todo}" ++ if uid in children.keys(): ++ total = len(children[uid]) ++ if total > 1: ++ for child in children[uid][:total-1]: ++ output = f"{output}\n ├─ {child}" ++ output = f"{output}\n └─ {children[uid][total-1]}" ++ ++ return output + + def _due_colour(self, todo: Todo) -> str: + now = self.now if isinstance(todo.due, datetime) else self.now.date() +@@ -251,6 +274,7 @@ class HumanizedFormatter(DefaultFormatter): + + class PorcelainFormatter(DefaultFormatter): + def _todo_as_dict(self, todo): ++ format_relation = lambda tup: {"reltype": tup[0], "uid": tup[1]} if tup else None + return { + "completed": todo.is_completed, + "start": self.format_datetime(todo.start), +@@ -264,6 +288,7 @@ class PorcelainFormatter(DefaultFormatter): + "location": todo.location, + "description": todo.description, + "completed_at": self.format_datetime(todo.completed_at), ++ "relation": format_relation(todo.relation), + } + + def compact(self, todo: Todo) -> str: +-- +2.39.3 + diff --git a/os/etc/portage/patches/app-misc/todoman/0004-fix-time-tests.patch b/os/etc/portage/patches/app-misc/todoman/0004-fix-time-tests.patch new file mode 100644 index 0000000..52a7b8b --- /dev/null +++ b/os/etc/portage/patches/app-misc/todoman/0004-fix-time-tests.patch @@ -0,0 +1,43 @@ +From d22203bc16f64a566896da41b3cba9d6c8bd1617 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Wed, 18 Jan 2023 18:11:55 +0100 +Subject: [PATCH 4/4] fix time tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + tests/test_formatter.py | 2 +- + tests/test_porcelain.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/test_formatter.py b/tests/test_formatter.py +index 4409b43..0ed960f 100644 +--- a/tests/test_formatter.py ++++ b/tests/test_formatter.py +@@ -135,7 +135,7 @@ def test_parse_datetime(default_formatter): + # for this one: + with freeze_time("2017-03-04"): + parsed = default_formatter.parse_datetime("Mon Mar 6 22:50:52 -03 2017") +- assert parsed == datetime(2017, 3, 6, 20, 17).replace(tzinfo=tz) ++ assert parsed == datetime(2017, 3, 6, 19, 17).replace(tzinfo=tz) + + assert default_formatter.parse_datetime("") is None + +diff --git a/tests/test_porcelain.py b/tests/test_porcelain.py +index bc2deaa..0043a3d 100644 +--- a/tests/test_porcelain.py ++++ b/tests/test_porcelain.py +@@ -92,7 +92,7 @@ def test_list_due_date(tmpdir, runner, create): + "completed": True, + "completed_at": None, + "description": "", +- "due": 1451692800, ++ "due": 1451689200, + "id": 1, + "list": "default", + "location": "Wherever", +-- +2.39.3 + diff --git a/os/etc/portage/patches/dev-libs/bemenu/0003-add-bemenu-drun-implementation.patch b/os/etc/portage/patches/dev-libs/bemenu/0003-add-bemenu-drun-implementation.patch new file mode 100644 index 0000000..26bc121 --- /dev/null +++ b/os/etc/portage/patches/dev-libs/bemenu/0003-add-bemenu-drun-implementation.patch @@ -0,0 +1,391 @@ +From cb6709bc9fd7e6c9fbbd817141b4b23acd435c97 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Sat, 13 May 2023 17:50:45 +0900 +Subject: [PATCH 3/3] add bemenu-drun implementation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + GNUmakefile | 6 +- + client/bemenu-drun.c | 343 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 348 insertions(+), 1 deletion(-) + create mode 100644 client/bemenu-drun.c + +diff --git a/GNUmakefile b/GNUmakefile +index 198088d..52646cf 100644 +--- a/GNUmakefile ++++ b/GNUmakefile +@@ -22,7 +22,7 @@ override CPPFLAGS += -D_DEFAULT_SOURCE -Ilib + + libs = libbemenu.so + pkgconfigs = bemenu.pc +-bins = bemenu bemenu-run ++bins = bemenu bemenu-run bemenu-drun + mans = bemenu.1 + renderers = bemenu-renderer-x11.so bemenu-renderer-curses.so bemenu-renderer-wayland.so + all: $(bins) $(renderers) $(mans) +@@ -108,6 +108,10 @@ common.a: client/common/common.c client/common/common.h + bemenu: common.a client/bemenu.c + bemenu-run: common.a client/bemenu-run.c + ++bemenu-drun: private override LDLIBS += $(shell $(PKG_CONFIG) --libs glib-2.0 gio-unix-2.0) -lm ++bemenu-drun: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I glib-2.0 gio-unix-2.0) ++bemenu-drun: common.a client/bemenu-drun.c ++ + install-pkgconfig: $(pkgconfigs) + mkdir -p "$(DESTDIR)$(PREFIX)$(libdir)/pkgconfig" + cp $^ "$(DESTDIR)$(PREFIX)$(libdir)/pkgconfig" +diff --git a/client/bemenu-drun.c b/client/bemenu-drun.c +new file mode 100644 +index 0000000..705061e +--- /dev/null ++++ b/client/bemenu-drun.c +@@ -0,0 +1,343 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "common/common.h" ++ ++#include ++ ++static struct client client = { ++ .filter_mode = BM_FILTER_MODE_DMENU, ++ .title = "bemenu-drun", ++ .monitor = -1, ++}; ++ ++struct paths { ++ char *path; ++ char *paths; ++}; ++ ++struct desktopfile { ++ const char *path; ++ const char *name; ++ const char *exec; ++}; ++ ++static char* ++c_strdup(const char *str) ++{ ++ return cstrcopy(str, strlen(str)); ++} ++ ++static char* ++strip_slash(char *str) ++{ ++ size_t size = strlen(str); ++ if (size > 0) ++ for (char *s = str + size - 1; *s == '/'; --s) ++ *s = 0; ++ return str; ++} ++ ++static char * ++append(char *base, const char *str) ++{ ++ char *base_ = base ? c_strdup(base) : ""; ++ ++ size_t len = ++ (base ? strlen(base) : 0) + ++ (str ? strlen(str) : 0) + ++ 1; ++ ++ base = realloc(base, len); ++ snprintf(base, len, "%s%s", base_, str); ++ return base; ++} ++ ++ ++static const char* ++get_application_paths(struct paths *state) ++{ ++ if (state->path && !*state->path) { ++ free(state->paths); ++ return NULL; ++ } ++ ++ if (!state->paths) { ++ const char *xdgdirs; ++ if (!(xdgdirs = getenv("XDG_DATA_DIRS")) || !xdgdirs[0]) ++ xdgdirs = "/usr/local/share/:/usr/share/"; ++ ++ const char *xdghome; ++ if(!(xdghome = getenv("XDG_DATA_HOME")) || !xdghome[0]) ++ xdghome = append(getenv("HOME"), "/.local/share/"); ++ ++ char *paths = NULL; ++ paths = append(paths, xdghome); ++ paths = append(paths, ":"); ++ paths = append(paths, xdgdirs); ++ ++ state->path = state->paths = paths; ++ } ++ ++ if (!state->path || !state->paths) ++ return NULL; ++ ++ char *path; ++ do { ++ size_t f; ++ path = state->path; ++ if ((f = strcspn(state->path, ":")) > 0) { ++ state->path += f + (path[f] ? 1 : 0); ++ path[f] = 0; ++ } else { ++ state->path += 1; ++ } ++ ++ if (!*path) { ++ free(state->paths); ++ return NULL; ++ } ++ } while (path[0] != '/'); ++ ++ char *appdir = NULL; ++ appdir = append(appdir, strip_slash(path)); ++ appdir = append(appdir, "/applications"); ++ ++ return appdir; ++} ++ ++static int ++compare(const void *a, const void *b) ++{ ++ const struct bm_item *ia = *(struct bm_item**)a, *ib = *(struct bm_item**)b; ++ return strcmp(bm_item_get_text(ia), bm_item_get_text(ib)); ++} ++ ++static void ++read_items_to_menu_from_desktopfile(struct bm_menu *menu, const char *path) ++{ ++ assert(menu && path); ++ ++ GKeyFile *file = g_key_file_new(); ++ if (!g_key_file_load_from_file(file, path, G_KEY_FILE_NONE, NULL)) ++ return; ++ ++ const char *group = "Desktop Entry"; ++ ++ if (g_key_file_get_boolean(file, group, "Hidden", NULL) ++ || g_key_file_get_boolean(file, group, "NoDisplay", NULL)) ++ goto cleanup; ++ ++ struct desktopfile *userdata = malloc(sizeof(struct desktopfile)); ++ userdata->path = c_strdup(path); ++ ++ if (!(userdata->name = g_key_file_get_locale_string(file, group, "Name", NULL, NULL))) ++ goto cleanup; ++ ++ char *rawexec; ++ if (!(rawexec = g_key_file_get_string(file, group, "Exec", NULL))) ++ goto cleanup; ++ ++ char *exec = NULL; ++ ++ bool terminal = g_key_file_get_boolean(file, group, "Terminal", NULL); ++ if (terminal) { ++ char *terminal_command = NULL; ++ if (!(terminal_command = getenv("TERMINAL"))) { ++ fprintf(stderr, "%s requested to be run in a terminal. $TERMINAL not found, skipping...\n", userdata->name); ++ goto cleanup; ++ } ++ ++ exec = append(exec, terminal_command); ++ exec = append(exec, " "); ++ } ++ ++ char *search = rawexec; ++ char *last = rawexec; ++ while ((search = strchr(search, '%')) != NULL) { ++ search[0] = '\0'; ++ ++ exec = append(exec, last); ++ ++ switch (search[1]) { ++ case 'i': ++ if (g_key_file_has_key(file, group, "Icon", NULL)) { ++ exec = append(exec, "--icon "); ++ exec = append(exec, g_key_file_get_string(file, group, "Icon", NULL)); ++ } ++ break; ++ case 'c': ++ exec = append(exec, (char *)userdata->name); ++ break; ++ case 'k': ++ exec = append(exec, (char*)userdata->path); ++ break; ++ } ++ ++ search += 2; ++ last = search; ++ } ++ exec = append(exec, last); ++ free(rawexec); ++ userdata->exec = exec; ++ ++ struct bm_item *item; ++ if ((item = bm_item_new(userdata->name))) { ++ bm_item_set_userdata(item, userdata); ++ bm_menu_add_item(menu, item); ++ } ++ ++cleanup: ++ g_key_file_unref(file); ++} ++ ++static void ++read_items_to_menu_from_application_dir(struct bm_menu *menu, const char *path) ++{ ++ assert(menu && path); ++ ++ DIR *dir; ++ if (!(dir = opendir(path))) ++ return; ++ ++ struct dirent *file; ++ while ((file = readdir(dir))) { ++ if (file->d_type == DT_DIR || (strlen(file->d_name) && file->d_name[0] == '.')) ++ continue; ++ ++ const char *extension = strrchr(file->d_name, '.'); ++ if (extension == NULL || strcmp(extension, ".desktop")) ++ continue; ++ ++ size_t len = strlen(path) + 1 + strlen(file->d_name) + 1; ++ char *desktopfile = malloc(len); ++ snprintf(desktopfile, len, "%s/%s", path, file->d_name); ++ ++ read_items_to_menu_from_desktopfile(menu, desktopfile); ++ ++ free(desktopfile); ++ } ++ ++ closedir(dir); ++ ++ uint32_t count; ++ struct bm_item **items = bm_menu_get_items(menu, &count); ++ qsort(items, count, sizeof(struct bm_item*), compare); ++ ++ bool unique = true; ++ for (uint32_t i = 0; i + 1 < count; i += unique) { ++ if (!(unique = strcmp(bm_item_get_text(items[i]), bm_item_get_text(items[i + 1])))) { ++ bm_item_free(items[i]); ++ bm_menu_remove_item_at(menu, i); ++ items = bm_menu_get_items(menu, &count); ++ } ++ } ++} ++ ++static void ++read_items_to_menu_from_appdirs(struct bm_menu *menu) ++{ ++ assert(menu); ++ ++ const char *path; ++ struct paths state; ++ memset(&state, 0, sizeof(state)); ++ ++ while ((path = get_application_paths(&state))) { ++ read_items_to_menu_from_application_dir(menu, path); ++ } ++} ++ ++static inline void ignore_ret(int useless, ...) { (void)useless; } ++ ++static void ++launch(const struct client *client, const char *bin) ++{ ++ if (!bin) ++ return; ++ ++ if (!client->fork || fork() == 0) { ++ if (client->fork) { ++ setsid(); ++ ignore_ret(0, freopen("/dev/null", "w", stdout)); ++ ignore_ret(0, freopen("/dev/null", "w", stderr)); ++ } ++ ++ char **tokens; ++ if (!(tokens = tokenize_quoted_to_argv(bin, NULL, NULL))) ++ _exit(EXIT_FAILURE); ++ ++ execvp(tokens[0], tokens); ++ _exit(EXIT_SUCCESS); ++ } ++} ++ ++static void ++drun_launch(const struct client *client, const char *path) ++{ ++ assert(client && path); ++ ++ GDesktopAppInfo *info = g_desktop_app_info_new_from_filename(path); ++ GAppLaunchContext *context = g_app_launch_context_new(); ++ GError *error = NULL; ++ ++ if (!g_app_info_launch((GAppInfo *)info, NULL, context, &error)) ++ _exit(EXIT_FAILURE); ++ ++ g_clear_error(&error); ++ g_object_unref(context); ++ g_object_unref(info); ++} ++ ++static void ++item_cb(const struct client *client, struct bm_item *item) ++{ ++ (void)client; ++ ++ const struct desktopfile *userdata; ++ ++ if (!(userdata = bm_item_get_userdata(item))) ++ return; ++ ++ if (client->no_exec) { ++ printf("%s\n", userdata->exec); ++ } else { ++ if (getenv("BEMENU_NO_DRUN_LAUNCH")) ++ launch(client, userdata->exec); ++ else ++ drun_launch(client, userdata->path); ++ } ++} ++ ++int ++main(int argc, char **argv) ++{ ++ struct sigaction action = { ++ .sa_handler = SIG_DFL, ++ .sa_flags = SA_NOCLDWAIT ++ }; ++ ++ // do not care about childs ++ sigaction(SIGCHLD, &action, NULL); ++ ++ if (!bm_init()) ++ return EXIT_FAILURE; ++ ++ parse_args(&client, &argc, &argv); ++ ++ struct bm_menu *menu; ++ if (!(menu = menu_with_options(&client))) ++ return EXIT_FAILURE; ++ ++ read_items_to_menu_from_appdirs(menu); ++ const enum bm_run_result status = run_menu(&client, menu, item_cb); ++ bm_menu_free(menu); ++ return (status == BM_RUN_RESULT_SELECTED ? EXIT_SUCCESS : EXIT_FAILURE); ++} ++ ++/* vim: set ts=8 sw=4 tw=0 :*/ +-- +2.39.3 + diff --git a/os/etc/portage/patches/dev-python/mdformat/0001-Allow-configuration-of-thematic-break-and-list-marke.patch b/os/etc/portage/patches/dev-python/mdformat/0001-Allow-configuration-of-thematic-break-and-list-marke.patch new file mode 100644 index 0000000..21d59d3 --- /dev/null +++ b/os/etc/portage/patches/dev-python/mdformat/0001-Allow-configuration-of-thematic-break-and-list-marke.patch @@ -0,0 +1,134 @@ +From bfd6a4a64467410f4473d7f5d82c8711ac524367 Mon Sep 17 00:00:00 2001 +From: James Quilty +Date: Sat, 27 Nov 2021 12:22:05 +1300 +Subject: [PATCH 1/3] Allow configuration of thematic break and list markers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Moves thematic break axnd list marker defaults to the DEFAULT_OPTS dictionary and allows modification of the default values via a configuration file when they are used. + +Signed-off-by: Robert Günzler +--- + src/mdformat/_conf.py | 11 +++++++++++ + src/mdformat/renderer/_context.py | 14 ++++++++++---- + src/mdformat/renderer/_util.py | 22 ++++++++++++++++------ + 3 files changed, 37 insertions(+), 10 deletions(-) + +diff --git a/src/mdformat/_conf.py b/src/mdformat/_conf.py +index b42f008..17fab67 100644 +--- a/src/mdformat/_conf.py ++++ b/src/mdformat/_conf.py +@@ -10,6 +10,12 @@ DEFAULT_OPTS = { + "wrap": "keep", + "number": False, + "end_of_line": "lf", ++ "primary_bullet_list_marker": "-", ++ "secondary_bullet_list_marker": "*", ++ "primary_ordered_list_marker": ".", ++ "secondary_ordered_list_marker": ")", ++ "thematic_break_character": "_", ++ "thematic_break_width": 70, + } + + +@@ -58,6 +64,11 @@ def _validate_values(opts: Mapping, conf_path: Path) -> None: + if "number" in opts: + if not isinstance(opts["number"], bool): + raise InvalidConfError(f"Invalid 'number' value in {conf_path}") ++ if "primary_bullet_list_marker" in opts: ++ if opts["primary_bullet_list_marker"] not in {"*", "+", "-"}: ++ raise InvalidConfError( ++ f"Invalid 'primary_bullet_list_marker' value in {conf_path}" ++ ) + + + def _validate_keys(opts: Mapping, conf_path: Path) -> None: +diff --git a/src/mdformat/renderer/_context.py b/src/mdformat/renderer/_context.py +index a9e837f..b2a2e2c 100644 +--- a/src/mdformat/renderer/_context.py ++++ b/src/mdformat/renderer/_context.py +@@ -53,8 +53,14 @@ def make_render_children(separator: str) -> Render: + + + def hr(node: RenderTreeNode, context: RenderContext) -> str: +- thematic_break_width = 70 +- return "_" * thematic_break_width ++ # options: Mapping[str, Any] ++ thematic_break_width = context.options.get("mdformat", {}).get( ++ "thematic_break_width", DEFAULT_OPTS["thematic_break_width"] ++ ) ++ thematic_break_character = context.options.get("mdformat", {}).get( ++ "thematic_break_character", DEFAULT_OPTS["thematic_break_character"] ++ ) ++ return thematic_break_character * thematic_break_width + + + def code_inline(node: RenderTreeNode, context: RenderContext) -> str: +@@ -463,7 +469,7 @@ def list_item(node: RenderTreeNode, context: RenderContext) -> str: + + + def bullet_list(node: RenderTreeNode, context: RenderContext) -> str: +- marker_type = get_list_marker_type(node) ++ marker_type = get_list_marker_type(node, context) + first_line_indent = " " + indent = " " * len(marker_type + first_line_indent) + block_separator = "\n" if is_tight_list(node) else "\n\n" +@@ -494,7 +500,7 @@ def ordered_list(node: RenderTreeNode, context: RenderContext) -> str: + consecutive_numbering = context.options.get("mdformat", {}).get( + "number", DEFAULT_OPTS["number"] + ) +- marker_type = get_list_marker_type(node) ++ marker_type = get_list_marker_type(node, context) + first_line_indent = " " + block_separator = "\n" if is_tight_list(node) else "\n\n" + list_len = len(node.children) +diff --git a/src/mdformat/renderer/_util.py b/src/mdformat/renderer/_util.py +index 2b3f5c3..0cf599f 100644 +--- a/src/mdformat/renderer/_util.py ++++ b/src/mdformat/renderer/_util.py +@@ -6,9 +6,10 @@ import re + from typing import TYPE_CHECKING + + from mdformat import codepoints ++from mdformat._conf import DEFAULT_OPTS + + if TYPE_CHECKING: +- from mdformat.renderer import RenderTreeNode ++ from mdformat.renderer import RenderContext, RenderTreeNode + + # Regex that finds character references. + # The reference can be either +@@ -72,15 +73,24 @@ def maybe_add_link_brackets(link: str) -> str: + return link + + +-def get_list_marker_type(node: RenderTreeNode) -> str: ++def get_list_marker_type(node: RenderTreeNode, context: RenderContext) -> str: + if node.type == "bullet_list": + mode = "bullet" +- primary_marker = "-" +- secondary_marker = "*" ++ primary_marker = context.options.get("mdformat", {}).get( ++ "primary_bullet_list_marker", DEFAULT_OPTS["primary_bullet_list_marker"] ++ ) ++ secondary_marker = context.options.get("mdformat", {}).get( ++ "secondary_bullet_list_marker", DEFAULT_OPTS["secondary_bullet_list_marker"] ++ ) + else: + mode = "ordered" +- primary_marker = "." +- secondary_marker = ")" ++ primary_marker = context.options.get("mdformat", {}).get( ++ "primary_ordered_list_marker", DEFAULT_OPTS["primary_ordered_list_marker"] ++ ) ++ secondary_marker = context.options.get("mdformat", {}).get( ++ "secondary_ordered_list_marker", ++ DEFAULT_OPTS["secondary_ordered_list_marker"], ++ ) + consecutive_lists_count = 1 + current = node + while True: +-- +2.39.1 + diff --git a/os/etc/portage/patches/dev-python/mdformat/0002-Add-configuration-option-to-enable-disable-escaping-.patch b/os/etc/portage/patches/dev-python/mdformat/0002-Add-configuration-option-to-enable-disable-escaping-.patch new file mode 100644 index 0000000..d61fbe0 --- /dev/null +++ b/os/etc/portage/patches/dev-python/mdformat/0002-Add-configuration-option-to-enable-disable-escaping-.patch @@ -0,0 +1,103 @@ +From 01dfce1f9fdaa2ccff24dbffbf6a57f11400852c Mon Sep 17 00:00:00 2001 +From: James Quilty +Date: Sat, 27 Nov 2021 14:12:19 +1300 +Subject: [PATCH 2/3] Add configuration option to enable/disable escaping of + square brackets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Adds a boolean entry 'escape_square_brackets' to the DEFAULT_OPTS dictionary and allows modification of the default value via a configuration file. Tests the boolean value in _context.text() and only escapes square brackets if this option is set to True. + +Escaped square brackets in the source are not unescaped; escaped and unescaped square brackets in the source are preserved in the formatted output when 'escape_square_brackets' is False. + +Signed-off-by: Robert Günzler +--- + src/mdformat/_conf.py | 43 +++++++++++++++++++++++++++---- + src/mdformat/renderer/_context.py | 7 +++-- + 2 files changed, 43 insertions(+), 7 deletions(-) + +diff --git a/src/mdformat/_conf.py b/src/mdformat/_conf.py +index 17fab67..7dcf447 100644 +--- a/src/mdformat/_conf.py ++++ b/src/mdformat/_conf.py +@@ -16,6 +16,7 @@ DEFAULT_OPTS = { + "secondary_ordered_list_marker": ")", + "thematic_break_character": "_", + "thematic_break_width": 70, ++ "escape_square_brackets": True, + } + + +@@ -64,11 +65,43 @@ def _validate_values(opts: Mapping, conf_path: Path) -> None: + if "number" in opts: + if not isinstance(opts["number"], bool): + raise InvalidConfError(f"Invalid 'number' value in {conf_path}") +- if "primary_bullet_list_marker" in opts: +- if opts["primary_bullet_list_marker"] not in {"*", "+", "-"}: +- raise InvalidConfError( +- f"Invalid 'primary_bullet_list_marker' value in {conf_path}" +- ) ++ if "primary_bullet_list_marker" in opts and opts[ ++ "primary_bullet_list_marker" ++ ] not in {"*", "+", "-"}: ++ raise InvalidConfError( ++ f"Invalid 'primary_bullet_list_marker' value in {conf_path}" ++ ) ++ if "secondary_bullet_list_marker" in opts and opts[ ++ "secondary_bullet_list_marker" ++ ] not in {"*", "+", "-"}: ++ raise InvalidConfError( ++ f"Invalid 'secondary_bullet_list_marker' value in {conf_path}" ++ ) ++ # if "primary_ordered_list_marker" in opts and opts[ ++ # "primary_ordered_list_marker" ++ # ] not in {".", ")"}: ++ # raise InvalidConfError( ++ # f"Invalid 'primary_ordered_list_marker' value in {conf_path}" ++ # ) ++ # if "secondary_ordered_list_marker" in opts and opts[ ++ # "secondary_ordered_list_marker" ++ # ] not in {".", ")"}: ++ # raise InvalidConfError( ++ # f"Invalid 'secondary_ordered_list_marker' value in {conf_path}" ++ # ) ++ # if "thematic_break_width" in opts and 3 < opts["thematic_break_width"] > 120: ++ # raise InvalidConfError( ++ # f"Invalid 'thematic_break_width' value in {conf_path} " ++ # f"(must be between 3 and 120)" ++ # ) ++ # if "escape_square_brackets" in opts and opts["escape_square_brackets"] not in { ++ # True, ++ # False, ++ # }: ++ # raise InvalidConfError( ++ # f"Invalid 'escape_square_brackets' value in {conf_path}" ++ # f"(must be 'true' or 'false')" ++ # ) + + + def _validate_keys(opts: Mapping, conf_path: Path) -> None: +diff --git a/src/mdformat/renderer/_context.py b/src/mdformat/renderer/_context.py +index b2a2e2c..80788f9 100644 +--- a/src/mdformat/renderer/_context.py ++++ b/src/mdformat/renderer/_context.py +@@ -122,10 +122,13 @@ def text(node: RenderTreeNode, context: RenderContext) -> str: + + text = escape_asterisk_emphasis(text) # Escape emphasis/strong marker. + text = escape_underscore_emphasis(text) # Escape emphasis/strong marker. +- text = text.replace("[", "\\[") # Escape link label enclosure +- text = text.replace("]", "\\]") # Escape link label enclosure + text = text.replace("<", "\\<") # Escape URI enclosure + text = text.replace("`", "\\`") # Escape code span marker ++ if context.options.get("mdformat", {}).get( ++ "escape_square_brackets", DEFAULT_OPTS["escape_square_brackets"] ++ ): ++ text = text.replace("[", "\\[") # Escape link label enclosure ++ text = text.replace("]", "\\]") # Escape link label enclosure + + # Escape "&" if it starts a sequence that can be interpreted as + # a character reference. +-- +2.39.1 + diff --git a/os/etc/portage/patches/dev-python/mdformat/0003-Add-configuration-option-to-enable-disable-HTML-enti.patch b/os/etc/portage/patches/dev-python/mdformat/0003-Add-configuration-option-to-enable-disable-HTML-enti.patch new file mode 100644 index 0000000..2131a76 --- /dev/null +++ b/os/etc/portage/patches/dev-python/mdformat/0003-Add-configuration-option-to-enable-disable-HTML-enti.patch @@ -0,0 +1,77 @@ +From d74027fc27c56e2a041a2188559d9bb9d9ec725b Mon Sep 17 00:00:00 2001 +From: James Quilty +Date: Sat, 27 Nov 2021 17:05:03 +1300 +Subject: [PATCH 3/3] Add configuration option to enable/disable HTML entity + substitution +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Adds a boolean entry 'entity_substitution' to the DEFAULT_OPTS dictionary and allows modification of the default value via a configuration file. Tests the boolean value in _util.build_mdit() and disables the markdown-it-py 'entity' rule if this option is set to False. Only escapes '&' in _context.text() if 'entity_substitution' is True. + +Signed-off-by: Robert Günzler +--- + src/mdformat/_conf.py | 1 + + src/mdformat/_util.py | 6 ++++++ + src/mdformat/renderer/_context.py | 9 ++++++--- + 3 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/src/mdformat/_conf.py b/src/mdformat/_conf.py +index 7dcf447..2fadcd1 100644 +--- a/src/mdformat/_conf.py ++++ b/src/mdformat/_conf.py +@@ -17,6 +17,7 @@ DEFAULT_OPTS = { + "thematic_break_character": "_", + "thematic_break_width": 70, + "escape_square_brackets": True, ++ "entity_substitution": True, + } + + +diff --git a/src/mdformat/_util.py b/src/mdformat/_util.py +index 5fa2f95..2f88a2b 100644 +--- a/src/mdformat/_util.py ++++ b/src/mdformat/_util.py +@@ -13,6 +13,7 @@ from markdown_it import MarkdownIt + from markdown_it.renderer import RendererHTML + + from mdformat._compat import Literal ++from mdformat._conf import DEFAULT_OPTS + import mdformat.plugins + + NULL_CTX = nullcontext() +@@ -43,6 +44,11 @@ def build_mdit( + lang: mdformat.plugins.CODEFORMATTERS[lang] for lang in codeformatters + } + ++ if mdformat_opts.get("entity_substitution", DEFAULT_OPTS["entity_substitution"]): ++ mdit.enable("entity") ++ else: ++ mdit.disable("entity") ++ + return mdit + + +diff --git a/src/mdformat/renderer/_context.py b/src/mdformat/renderer/_context.py +index 80788f9..7280523 100644 +--- a/src/mdformat/renderer/_context.py ++++ b/src/mdformat/renderer/_context.py +@@ -130,9 +130,12 @@ def text(node: RenderTreeNode, context: RenderContext) -> str: + text = text.replace("[", "\\[") # Escape link label enclosure + text = text.replace("]", "\\]") # Escape link label enclosure + +- # Escape "&" if it starts a sequence that can be interpreted as +- # a character reference. +- text = RE_CHAR_REFERENCE.sub(r"\\\g<0>", text) ++ if context.options.get("mdformat", {}).get( ++ "entity_substitution", DEFAULT_OPTS["entity_substitution"] ++ ): ++ # Escape "&" if it starts a sequence that can be interpreted as ++ # a character reference. ++ text = RE_CHAR_REFERENCE.sub(r"\\\g<0>", text) + + # The parser can give us consecutive newlines which can break + # the markdown structure. Replace two or more consecutive newlines +-- +2.39.1 + diff --git a/os/etc/portage/patches/dev-tex/tectonic/0001-v2cli-add-exec-to-build.patch b/os/etc/portage/patches/dev-tex/tectonic/0001-v2cli-add-exec-to-build.patch new file mode 100644 index 0000000..787cf66 --- /dev/null +++ b/os/etc/portage/patches/dev-tex/tectonic/0001-v2cli-add-exec-to-build.patch @@ -0,0 +1,54 @@ +From 6a4aa55750f7ed7d9d1508bc84d3eb77d0ed9754 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Wed, 11 Jan 2023 18:22:47 +0100 +Subject: [PATCH] v2cli: add exec to build +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + src/bin/tectonic/v2cli.rs | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/bin/tectonic/v2cli.rs b/src/bin/tectonic/v2cli.rs +index 2cebe5f6..a73ef3af 100644 +--- a/src/bin/tectonic/v2cli.rs ++++ b/src/bin/tectonic/v2cli.rs +@@ -235,9 +235,9 @@ pub struct BuildCommand { + #[structopt(long = "print", short)] + print_stdout: bool, + +- /// Open built document using system handler +- #[structopt(long)] +- open: bool, ++ /// Specify a target to be used by the build ++ #[structopt(long, short = "x")] ++ open: Option>, + + /// Specify a target to be used by the build + #[structopt(long, help = "Specify the target of the build.")] +@@ -282,14 +282,16 @@ impl BuildCommand { + + crate::compile::run_and_report(builder, status)?; + +- if self.open { ++ if let Some(ref value) = self.open { + let out_file = doc.output_main_file(output_name); +- + if is_config_test_mode_activated() { + tt_note!(status, "not opening `{}` -- test mode", out_file.display()); + } else { +- tt_note!(status, "opening `{}`", out_file.display()); +- if let Err(e) = open::that(&out_file) { ++ let result = match value { ++ None => open::that(&out_file), // system handler ++ Some(ref command) => open::with(&out_file, command), // custom command handler ++ }; ++ if let Err(e) = result { + tt_error!( + status, + "failed to open `{}` with system handler", +-- +2.39.3 + diff --git a/os/etc/portage/patches/gui-apps/mako/0001-Color-in-svg-icons-with-text-color.patch b/os/etc/portage/patches/gui-apps/mako/0001-Color-in-svg-icons-with-text-color.patch new file mode 100644 index 0000000..0546110 --- /dev/null +++ b/os/etc/portage/patches/gui-apps/mako/0001-Color-in-svg-icons-with-text-color.patch @@ -0,0 +1,142 @@ +From a25bbd08d33e5f827735c152d47b4d3accf68bdd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Tue, 4 May 2021 22:48:50 +0200 +Subject: [PATCH 1/2] Color in svg icons with text-color +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The implementation is largely taken from gtk. +Adds a dependency on gio. + +Signed-off-by: Robert Günzler +--- + icon.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++--- + meson.build | 4 ++- + 2 files changed, 71 insertions(+), 4 deletions(-) + +diff --git a/icon.c b/icon.c +index e1aa64f..76c4e47 100644 +--- a/icon.c ++++ b/icon.c +@@ -18,6 +18,7 @@ + #ifdef HAVE_ICONS + + #include ++#include + #include "cairo-pixbuf.h" + + static bool validate_icon_name(const char* icon_name) { +@@ -41,12 +42,76 @@ static bool validate_icon_name(const char* icon_name) { + return true; + } + +-static GdkPixbuf *load_image(const char *path) { ++static GdkPixbuf *load_svg(const char *path, struct mako_style *style, GError **err) { ++ // https://gitlab.gnome.org/GNOME/gtk/-/blob/master/gtk/gdkpixbufutils.c#L335 ++ ++ char *data; ++ gsize size; ++ char *escaped_file_data; ++ int icon_width, icon_height; ++ ++ if (!g_file_get_contents(path, &data, &size, err)) { ++ return NULL; ++ } ++ ++ /* Fetch size from the original icon */ ++ { ++ GInputStream *stream = g_memory_input_stream_new_from_data(data, size, NULL); ++ GdkPixbuf *reference = gdk_pixbuf_new_from_stream(stream, NULL, err); ++ ++ g_object_unref(stream); ++ ++ if (!reference) { ++ return NULL; ++ } ++ ++ icon_width = gdk_pixbuf_get_width(reference); ++ icon_height = gdk_pixbuf_get_height(reference); ++ g_object_unref(reference); ++ } ++ ++ escaped_file_data = g_base64_encode((guchar *) data, size); ++ char *str = mako_asprintf( ++ "\n" ++ "\n" ++ " \n" ++ " \n" ++ "", ++ icon_width, ++ icon_height, ++ style->colors.text, ++ escaped_file_data); ++ ++ GInputStream *stream = g_memory_input_stream_new_from_data(str, -1, g_free); ++ GdkPixbuf *ret = gdk_pixbuf_new_from_stream(stream, NULL, err); ++ ++ g_free(data); ++ g_free(escaped_file_data); ++ g_object_unref(stream); ++ ++ return ret; ++} ++ ++static GdkPixbuf *load_image(const char *path, struct mako_style *style) { + if (strlen(path) == 0) { + return NULL; + } + GError *err = NULL; +- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err); ++ GdkPixbuf *pixbuf; ++ // FIXME ok? or do we need to actually look at mime info? ++ if (strcmp(strrchr(path, '.'), ".svg") == 0) { ++ pixbuf = load_svg(path, style, &err); ++ } else { ++ pixbuf = gdk_pixbuf_new_from_file(path, &err); ++ } + if (!pixbuf) { + fprintf(stderr, "Failed to load icon (%s)\n", err->message); + g_error_free(err); +@@ -263,7 +328,7 @@ struct mako_icon *create_icon(struct mako_notification *notif) { + return NULL; + } + +- image = load_image(path); ++ image = load_image(path, ¬if->style); + free(path); + if (image == NULL) { + return NULL; +diff --git a/meson.build b/meson.build +index abda8b5..8024365 100644 +--- a/meson.build ++++ b/meson.build +@@ -47,7 +47,8 @@ endif + add_project_arguments('-DHAVE_' + sdbus.name().to_upper() + '=1', language: 'c') + + gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: get_option('icons')) +-if gdk_pixbuf.found() ++gio = dependency('gio-2.0', required: get_option('icons')) ++if gdk_pixbuf.found() and gio.found() + add_global_arguments('-DHAVE_ICONS=1', language: 'c') + endif + +@@ -88,6 +89,7 @@ executable( + sdbus, + pango, + pangocairo, ++ gio, + glib, + gobject, + realtime, +-- +2.39.3 + diff --git a/os/etc/portage/patches/gui-apps/mako/0002-allow-restoring-notifications-by-id.patch b/os/etc/portage/patches/gui-apps/mako/0002-allow-restoring-notifications-by-id.patch new file mode 100644 index 0000000..a1920d6 --- /dev/null +++ b/os/etc/portage/patches/gui-apps/mako/0002-allow-restoring-notifications-by-id.patch @@ -0,0 +1,120 @@ +From a965d297a4782bf6f1c2c58a92baa6712b0af3b2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Tue, 18 Jan 2022 14:24:51 +0100 +Subject: [PATCH 2/2] allow restoring notifications by id +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + dbus/mako.c | 32 ++++++++++++++++++++++++++++++-- + makoctl | 28 +++++++++++++++++++++++++--- + 2 files changed, 55 insertions(+), 5 deletions(-) + +diff --git a/dbus/mako.c b/dbus/mako.c +index 9fc0b01..57f58c5 100644 +--- a/dbus/mako.c ++++ b/dbus/mako.c +@@ -121,7 +121,7 @@ static int handle_invoke_action(sd_bus_message *msg, void *data, + return sd_bus_reply_method_return(msg, ""); + } + +-static int handle_restore_action(sd_bus_message *msg, void *data, ++static int handle_restore_last_action(sd_bus_message *msg, void *data, + sd_bus_error *ret_error) { + struct mako_state *state = data; + +@@ -140,6 +140,33 @@ done: + return sd_bus_reply_method_return(msg, ""); + } + ++static int handle_restore_action(sd_bus_message *msg, void *data, ++ sd_bus_error *ret_error) { ++ struct mako_state *state = data; ++ ++ if (wl_list_empty(&state->history)) { ++ goto done; ++ } ++ ++ uint32_t id = 0; ++ int ret = sd_bus_message_read(msg, "u", &id); ++ if (ret < 0) { ++ goto done; ++ } ++ ++ struct mako_notification *notif; ++ wl_list_for_each(notif, &state->history, link) { ++ if (notif->id == id || id == 0) break; ++ } ++ wl_list_remove(¬if->link); ++ ++ insert_notification(state, notif); ++ set_dirty(notif->surface); ++ ++done: ++ return sd_bus_reply_method_return(msg, ""); ++} ++ + static int handle_list(sd_bus_message *msg, struct wl_list *list) { + + sd_bus_message *reply = NULL; +@@ -442,7 +469,8 @@ static const sd_bus_vtable service_vtable[] = { + SD_BUS_METHOD("DismissLastNotification", "", "", handle_dismiss_last_notification, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("DismissNotification", "ub", "", handle_dismiss_notification, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("InvokeAction", "us", "", handle_invoke_action, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_METHOD("RestoreNotification", "", "", handle_restore_action, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("RestoreLastNotification", "", "", handle_restore_last_action, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("RestoreNotification", "ub", "", handle_restore_action, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ListNotifications", "", "aa{sv}", handle_list_notifications, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ListHistory", "", "aa{sv}", handle_list_history, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Reload", "", "", handle_reload, SD_BUS_VTABLE_UNPRIVILEGED), +diff --git a/makoctl b/makoctl +index b5298fe..ede8381 100755 +--- a/makoctl ++++ b/makoctl +@@ -10,8 +10,8 @@ usage() { + echo " [-a|--all] Dismiss all notifications" + echo " [-g|--group] Dismiss all the notifications" + echo " in the last notification's group" +- echo " restore Restore the most recently expired" +- echo " notification from the history buffer" ++ echo " restore [-n id] Restore a notification from the history" ++ echo " buffer, or the last if none is given" + echo " invoke [-n id] [action] Invoke an action on the notification" + echo " with the given id, or the last" + echo " notification if none is given" +@@ -104,7 +104,29 @@ case "$1" in + call InvokeAction "us" "$id" "$action" + ;; + "restore") +- call RestoreNotification ++ id=0 ++ while [ $# -gt 1 ]; do ++ case "$2" in ++ "-n") ++ if [ $# -lt 3 ]; then ++ echo >&2 "$0: Expected after '-n'" ++ exit 1 ++ fi ++ id=$3 ++ shift ++ ;; ++ *) ++ echo >&2 "$0: Unrecognized option: $2" ++ exit 1 ++ ;; ++ esac ++ shift ++ done ++ if [ "$id" -gt 0 ]; then ++ call RestoreNotification "u" "$id" ++ else ++ call RestoreLastNotification ++ fi + ;; + "menu") + shift 1 +-- +2.39.3 + diff --git a/os/etc/portage/patches/gui-apps/wlsunset/0001-Add-option-to-run-a-hook-when-changing-temperature.patch b/os/etc/portage/patches/gui-apps/wlsunset/0001-Add-option-to-run-a-hook-when-changing-temperature.patch new file mode 100644 index 0000000..68d351f --- /dev/null +++ b/os/etc/portage/patches/gui-apps/wlsunset/0001-Add-option-to-run-a-hook-when-changing-temperature.patch @@ -0,0 +1,120 @@ +From 7fa54af3b011f1b186a709b377d01ba6fdd64e1c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Mon, 26 Apr 2021 15:12:58 +0200 +Subject: [PATCH] Add option to run a hook when changing temperature +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + main.c | 34 ++++++++++++++++++++++++++++++++-- + wlsunset.1.scd | 5 +++++ + 2 files changed, 37 insertions(+), 2 deletions(-) + +diff --git a/main.c b/main.c +index 95330bf..2b9f722 100644 +--- a/main.c ++++ b/main.c +@@ -109,6 +109,7 @@ struct config { + time_t duration; + + struct str_vec output_names; ++ char *hook; + }; + + enum state { +@@ -182,6 +183,29 @@ static void print_trajectory(struct context *ctx) { + } + } + ++static char* phase_str(int low_temp, int high_temp, int temp) { ++ if (high_temp == temp) { ++ return "daytime"; ++ } else if (low_temp == temp) { ++ return "night"; ++ } else if ((high_temp - low_temp) >= 2) { ++ return "dusk"; ++ } else { ++ return "dawn"; ++ } ++} ++ ++static void run_hook(const struct context *ctx, const char *phase) { ++ if (!ctx->config.hook) return; ++ if (!phase) return; ++ ++ char *cmd = strcat(strcat(strdup(ctx->config.hook), " "), phase); ++ fprintf(stderr, "running hook for phase %s\n", phase); ++ ++ if (system(cmd)) {;} ++ free(cmd); ++} ++ + static int anim_kelvin_step = 25; + + static void recalc_stops(struct context *ctx, time_t now) { +@@ -781,6 +805,7 @@ static int wlrun(struct config cfg) { + + int temp = get_temperature(&ctx, now); + set_temperature(&ctx.outputs, temp, ctx.config.gamma); ++ run_hook(&ctx, phase_str(ctx.config.low_temp, ctx.config.high_temp, temp)); + + int old_temp = temp; + while (display_dispatch(display, -1) != -1) { +@@ -801,6 +826,7 @@ static int wlrun(struct config cfg) { + + set_temperature(&ctx.outputs, temp, ctx.config.gamma); + } ++ run_hook(&ctx, phase_str(ctx.config.low_temp, ctx.config.high_temp, temp)); + } + + return EXIT_SUCCESS; +@@ -829,7 +855,8 @@ static const char usage[] = "usage: %s [options]\n" + " -S set manual sunrise (e.g. 06:30)\n" + " -s set manual sunset (e.g. 18:30)\n" + " -d set manual duration in seconds (e.g. 1800)\n" +-" -g set gamma (default: 1.0)\n"; ++" -g set gamma (default: 1.0)\n" ++" -H set path to hook to execute on state change (e.g. /path/to/hook.sh)\n"; + + int main(int argc, char *argv[]) { + #ifdef SPEEDRUN +@@ -848,7 +875,7 @@ int main(int argc, char *argv[]) { + + int ret = EXIT_FAILURE; + int opt; +- while ((opt = getopt(argc, argv, "hvo:t:T:l:L:S:s:d:g:")) != -1) { ++ while ((opt = getopt(argc, argv, "hvo:t:T:l:L:S:s:d:g:H:")) != -1) { + switch (opt) { + case 'o': + str_vec_push(&config.output_names, optarg); +@@ -885,6 +912,9 @@ int main(int argc, char *argv[]) { + case 'g': + config.gamma = strtod(optarg, NULL); + break; ++ case 'H': ++ config.hook = optarg; ++ break; + case 'v': + printf("wlsunset version %s\n", WLSUNSET_VERSION); + ret = EXIT_SUCCESS; +diff --git a/wlsunset.1.scd b/wlsunset.1.scd +index c62f2bc..bd906a1 100644 +--- a/wlsunset.1.scd ++++ b/wlsunset.1.scd +@@ -40,6 +40,11 @@ wlr-gamma-control-unstable-v1 + *-g* + set gamma (default: 1.0) + ++*-H* ++ set path to a hook to execute on state change (e.g. /path/to/hook.sh) ++ ++ The hook will be called with the current phase as an argument. ++ + # EXAMPLE + + ``` +-- +2.35.1 + diff --git a/os/etc/portage/patches/gui-wm/sway/7226.patch b/os/etc/portage/patches/gui-wm/sway/7226.patch new file mode 100644 index 0000000..8db73d6 --- /dev/null +++ b/os/etc/portage/patches/gui-wm/sway/7226.patch @@ -0,0 +1,688 @@ +From 53d4cf1b93de202da22b7f2132e2086eace63ff6 Mon Sep 17 00:00:00 2001 +From: ShootingStarDragons +Date: Wed, 3 May 2023 14:21:27 +0800 +Subject: [PATCH] text_input: Implement input-method popups + +--- + .gitignore | 1 + + include/sway/input/text_input.h | 24 +++ + include/sway/output.h | 4 + + sway/desktop/output.c | 29 +++ + sway/desktop/render.c | 16 +- + sway/input/cursor.c | 26 +++ + sway/input/text_input.c | 350 +++++++++++++++++++++++++++++++- + sway/tree/container.c | 3 + + sway/tree/view.c | 3 + + 9 files changed, 448 insertions(+), 8 deletions(-) + +diff --git a/.gitignore b/.gitignore +index 1ec0cb5232..876a15a623 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -11,3 +11,4 @@ config-debug + wayland-*-protocol.* + /subprojects/wlroots + subprojects ++.cache +diff --git a/include/sway/input/text_input.h b/include/sway/input/text_input.h +index 4de96d4493..2dbd5920e9 100644 +--- a/include/sway/input/text_input.h ++++ b/include/sway/input/text_input.h +@@ -21,18 +21,37 @@ struct sway_input_method_relay { + struct sway_seat *seat; + + struct wl_list text_inputs; // sway_text_input::link ++ struct wl_list input_popups; // sway_input_popup::link + struct wlr_input_method_v2 *input_method; // doesn't have to be present + + struct wl_listener text_input_new; + + struct wl_listener input_method_new; + struct wl_listener input_method_commit; ++ struct wl_listener input_method_new_popup_surface; + struct wl_listener input_method_grab_keyboard; + struct wl_listener input_method_destroy; + + struct wl_listener input_method_keyboard_grab_destroy; + }; + ++struct sway_input_popup { ++ struct sway_input_method_relay *relay; ++ struct wlr_input_popup_surface_v2 *popup_surface; ++ ++ int x, y; ++ bool visible; ++ ++ struct wl_list link; ++ ++ struct wl_listener popup_map; ++ struct wl_listener popup_unmap; ++ struct wl_listener popup_destroy; ++ struct wl_listener popup_surface_commit; ++ ++ struct wl_listener focused_surface_unmap; ++}; ++ + struct sway_text_input { + struct sway_input_method_relay *relay; + +@@ -65,4 +84,9 @@ struct sway_text_input *sway_text_input_create( + struct sway_input_method_relay *relay, + struct wlr_text_input_v3 *text_input); + ++bool sway_input_popup_get_position( ++ struct sway_input_popup *popup, int *lx, int *ly); ++ ++void sway_input_popup_damage(struct sway_input_popup *popup); ++ + #endif +diff --git a/include/sway/output.h b/include/sway/output.h +index f6dc6af2bd..e63c9d1390 100644 +--- a/include/sway/output.h ++++ b/include/sway/output.h +@@ -155,6 +155,10 @@ void output_unmanaged_for_each_surface(struct sway_output *output, + void *user_data); + #endif + ++void output_input_popups_for_each_surface(struct sway_output *output, ++ struct wl_list *input_popups, sway_surface_iterator_func_t iterator, ++ void *user_data); ++ + void output_drag_icons_for_each_surface(struct sway_output *output, + struct wl_list *drag_icons, sway_surface_iterator_func_t iterator, + void *user_data); +diff --git a/sway/desktop/output.c b/sway/desktop/output.c +index fe1fa8af76..560270f4ea 100644 +--- a/sway/desktop/output.c ++++ b/sway/desktop/output.c +@@ -22,6 +22,7 @@ + #include "sway/input/input-manager.h" + #include "sway/input/seat.h" + #include "sway/ipc-server.h" ++#include "sway/input/text_input.h" + #include "sway/layers.h" + #include "sway/output.h" + #include "sway/server.h" +@@ -257,6 +258,31 @@ void output_unmanaged_for_each_surface(struct sway_output *output, + } + #endif + ++void output_input_popups_for_each_surface(struct sway_output *output, ++ struct wl_list *input_popups, sway_surface_iterator_func_t iterator, ++ void *user_data) { ++ struct sway_input_popup *popup; ++ wl_list_for_each(popup, input_popups, link) { ++ int lx, ly; ++ if (!sway_input_popup_get_position(popup, &lx, &ly)) { ++ continue; ++ } ++ if (!popup->popup_surface->surface->mapped || !popup->visible) { ++ continue; ++ } ++ ++ // damage the popup if surface is updated ++ sway_input_popup_damage(popup); ++ ++ double ox = lx - output->lx; ++ double oy = ly - output->ly; ++ ++ output_surface_for_each_surface(output, ++ popup->popup_surface->surface, ox, oy, ++ iterator, user_data); ++ } ++} ++ + void output_drag_icons_for_each_surface(struct sway_output *output, + struct wl_list *drag_icons, sway_surface_iterator_func_t iterator, + void *user_data) { +@@ -367,6 +393,9 @@ static void output_for_each_surface(struct sway_output *output, + output_layer_for_each_surface(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], + iterator, user_data); ++ output_input_popups_for_each_surface( ++ output, &input_manager_current_seat()->im_relay.input_popups, ++ iterator, user_data); + output_drag_icons_for_each_surface(output, &root->drag_icons, + iterator, user_data); + } +diff --git a/sway/desktop/render.c b/sway/desktop/render.c +index 2101404246..0d3834f6d6 100644 +--- a/sway/desktop/render.c ++++ b/sway/desktop/render.c +@@ -202,6 +202,15 @@ static void render_unmanaged(struct render_context *ctx, struct wl_list *unmanag + } + #endif + ++static void render_input_popups(struct render_context *ctx, struct wl_list *input_popups) { ++ struct render_data data = { ++ .alpha = 1.0f, ++ .ctx = ctx, ++ }; ++ output_input_popups_for_each_surface(ctx->output, input_popups, ++ render_surface_iterator, &data); ++} ++ + static void render_drag_icons(struct render_context *ctx, struct wl_list *drag_icons) { + struct render_data data = { + .alpha = 1.0f, +@@ -1076,6 +1085,10 @@ void output_render(struct render_context *ctx) { + goto renderer_end; + } + ++ struct sway_seat *seat = input_manager_current_seat(); ++ struct sway_container *focus = seat_get_focused_container(seat); ++ // here use seat ++ + if (output_has_opaque_overlay_layer_surface(output)) { + goto render_overlay; + } +@@ -1138,8 +1151,6 @@ void output_render(struct render_context *ctx) { + + render_seatops(ctx); + +- struct sway_seat *seat = input_manager_current_seat(); +- struct sway_container *focus = seat_get_focused_container(seat); + if (focus && focus->view) { + render_view_popups(ctx, focus->view, focus->alpha); + } +@@ -1149,6 +1160,7 @@ void output_render(struct render_context *ctx) { + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); + render_layer_popups(ctx, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); ++ render_input_popups(ctx, &seat->im_relay.input_popups); + render_drag_icons(ctx, &root->drag_icons); + + renderer_end: +diff --git a/sway/input/cursor.c b/sway/input/cursor.c +index d8ec11ac2d..cd9cbc8562 100644 +--- a/sway/input/cursor.c ++++ b/sway/input/cursor.c +@@ -37,6 +37,28 @@ static uint32_t get_current_time_msec(void) { + return now.tv_sec * 1000 + now.tv_nsec / 1000000; + } + ++static struct wlr_surface *input_popup_surface_at(struct sway_output *output, ++ struct sway_input_method_relay *relay, double ox, double oy, double *sx, double *sy) { ++ struct sway_input_popup *popup; ++ wl_list_for_each(popup, &relay->input_popups, link) { ++ int lx, ly; ++ if (!sway_input_popup_get_position(popup, &lx, &ly)) { ++ continue; ++ } ++ if (!popup->popup_surface->surface->mapped || !popup->visible) { ++ continue; ++ } ++ double _sx = ox - lx; ++ double _sy = oy - ly; ++ struct wlr_surface *sub = wlr_surface_surface_at( ++ popup->popup_surface->surface, _sx, _sy, sx, sy); ++ if (sub) { ++ return sub; ++ } ++ } ++ return NULL; ++} ++ + static struct wlr_surface *layer_surface_at(struct sway_output *output, + struct wl_list *layer, double ox, double oy, double *sx, double *sy) { + struct sway_layer_surface *sway_layer; +@@ -119,6 +141,10 @@ struct sway_node *node_at_coords( + return NULL; + } + ++ if ((*surface = input_popup_surface_at(output, ++ &seat->im_relay, ox, oy, sx, sy))) { ++ return NULL; ++ } + // check for unmanaged views + #if HAVE_XWAYLAND + struct wl_list *unmanaged = &root->xwayland_unmanaged; +diff --git a/sway/input/text_input.c b/sway/input/text_input.c +index 58911c2de4..05c867d6ff 100644 +--- a/sway/input/text_input.c ++++ b/sway/input/text_input.c +@@ -1,8 +1,14 @@ + #include ++#include + #include + #include "log.h" + #include "sway/input/seat.h" + #include "sway/input/text_input.h" ++#include "sway/tree/view.h" ++#include "sway/tree/container.h" ++#include "sway/desktop.h" ++#include "sway/output.h" ++#include "sway/layers.h" + + static struct sway_text_input *relay_get_focusable_text_input( + struct sway_input_method_relay *relay) { +@@ -26,6 +32,329 @@ static struct sway_text_input *relay_get_focused_text_input( + return NULL; + } + ++// damage the popup ++void sway_input_popup_damage(struct sway_input_popup *popup) { ++ if (!popup->visible) { ++ return; ++ } ++ ++ struct sway_text_input *text_input = ++ relay_get_focused_text_input(popup->relay); ++ if (text_input == NULL || text_input->input->focused_surface == NULL) { ++ return; ++ } ++ ++ struct wlr_surface *focused_surface = text_input->input->focused_surface; ++ struct wlr_layer_surface_v1 *layer_surface = ++ wlr_layer_surface_v1_try_from_wlr_surface(focused_surface); ++ if (layer_surface != NULL) { ++ struct sway_layer_surface *layer = ++ layer_from_wlr_layer_surface_v1(layer_surface); ++ output_damage_surface(layer->layer_surface->output->data, ++ layer->geo.x + popup->x, layer->geo.y + popup->y, ++ popup->popup_surface->surface, true); ++ return; ++ } ++ ++ struct sway_view *view = view_from_wlr_surface( ++ text_input->input->focused_surface); ++ if (view->container == NULL) { ++ sway_log(SWAY_INFO, "Tried to damage popup, but view is gone"); ++ return; ++ } ++ desktop_damage_surface(popup->popup_surface->surface, ++ view->container->surface_x - view->geometry.x + popup->x, ++ view->container->surface_y - view->geometry.y + popup->y, true); ++} ++ ++static void input_popup_update(struct sway_input_popup *popup) { ++ sway_input_popup_damage(popup); ++ ++ struct sway_text_input *text_input = ++ relay_get_focused_text_input(popup->relay); ++ ++ if (text_input == NULL || text_input->input->focused_surface == NULL) { ++ return; ++ } ++ ++ if (!popup->popup_surface->surface->mapped) { ++ return; ++ } ++ ++ bool cursor_rect = text_input->input->current.features ++ & WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE; ++ struct wlr_surface *focused_surface = text_input->input->focused_surface; ++ struct wlr_box cursor = text_input->input->current.cursor_rectangle; ++ ++ struct wlr_output *output; ++ struct wlr_box output_box; ++ struct wlr_box parent; ++ struct wlr_layer_surface_v1 *layer_surface = ++ wlr_layer_surface_v1_try_from_wlr_surface(focused_surface); ++ if (layer_surface != NULL) { ++ struct sway_layer_surface *layer = ++ layer_from_wlr_layer_surface_v1(layer_surface); ++ output = layer->layer_surface->output; ++ wlr_output_layout_get_box(root->output_layout, output, &output_box); ++ parent = layer->geo; ++ parent.x += output_box.x; ++ parent.y += output_box.y; ++ } else { ++ struct sway_view *view = view_from_wlr_surface(focused_surface); ++ output = wlr_output_layout_output_at(root->output_layout, ++ view->container->surface_x + view->geometry.x, ++ view->container->surface_y + view->geometry.y); ++ wlr_output_layout_get_box(root->output_layout, output, &output_box); ++ parent.x = view->container->surface_x + view->geometry.x; ++ parent.y = view->container->surface_y + view->geometry.y; ++ parent.width = view->geometry.width; ++ parent.height = view->geometry.height; ++ } ++ ++ if (!cursor_rect) { ++ cursor.x = 0; ++ cursor.y = 0; ++ cursor.width = parent.width; ++ cursor.height = parent.height; ++ } ++ ++ int popup_width = popup->popup_surface->surface->current.width; ++ int popup_height = popup->popup_surface->surface->current.height; ++ int x1 = parent.x + cursor.x; ++ int x2 = parent.x + cursor.x + cursor.width; ++ int y1 = parent.y + cursor.y; ++ int y2 = parent.y + cursor.y + cursor.height; ++ int x = x1; ++ int y = y2; ++ ++ int available_right = output_box.x + output_box.width - x1; ++ int available_left = x2 - output_box.x; ++ if (available_right < popup_width && available_left > available_right) { ++ x = x2 - popup_width; ++ } ++ ++ int available_down = output_box.y + output_box.height - y2; ++ int available_up = y1 - output_box.y; ++ if (available_down < popup_height && available_up > available_down) { ++ y = y1 - popup_height; ++ } ++ ++ popup->x = x - parent.x; ++ popup->y = y - parent.y; ++ ++ // Hide popup if cursor position is completely out of bounds ++ bool x1_in_bounds = (cursor.x >= 0 && cursor.x < parent.width); ++ bool y1_in_bounds = (cursor.y >= 0 && cursor.y < parent.height); ++ bool x2_in_bounds = (cursor.x + cursor.width >= 0 ++ && cursor.x + cursor.width < parent.width); ++ bool y2_in_bounds = (cursor.y + cursor.height >= 0 ++ && cursor.y + cursor.height < parent.height); ++ popup->visible = ++ (x1_in_bounds && y1_in_bounds) || (x2_in_bounds && y2_in_bounds); ++ ++ if (cursor_rect) { ++ struct wlr_box box = { ++ .x = x1 - x, ++ .y = y1 - y, ++ .width = cursor.width, ++ .height = cursor.height, ++ }; ++ wlr_input_popup_surface_v2_send_text_input_rectangle( ++ popup->popup_surface, &box); ++ } ++ ++ sway_input_popup_damage(popup); ++} ++ ++static void surface_send_enter_iterator(struct wlr_surface *surface, ++ int x, int y, void *data) { ++ struct wlr_output *wlr_output = data; ++ wlr_surface_send_enter(surface, wlr_output); ++} ++ ++static void surface_send_leave_iterator(struct wlr_surface *surface, ++ int x, int y, void *data) { ++ struct wlr_output *wlr_output = data; ++ wlr_surface_send_leave(surface, wlr_output); ++} ++ ++static void input_popup_send_outputs(struct sway_input_popup *popup, ++ wlr_surface_iterator_func_t iterator) { ++ struct sway_text_input *text_input = ++ relay_get_focused_text_input(popup->relay); ++ if (text_input == NULL || text_input->input->focused_surface == NULL) { ++ return; ++ } ++ struct wlr_surface *focused_surface = text_input->input->focused_surface; ++ struct wlr_layer_surface_v1 *layer_surface = ++ wlr_layer_surface_v1_try_from_wlr_surface(focused_surface); ++ if (layer_surface != NULL) { ++ struct sway_layer_surface *layer = ++ layer_from_wlr_layer_surface_v1(layer_surface); ++ wlr_surface_for_each_surface(popup->popup_surface->surface, ++ iterator, layer->layer_surface->output); ++ return; ++ } ++ struct sway_view *view = view_from_wlr_surface(focused_surface); ++ for (int i = 0; i < view->container->outputs->length; i++) { ++ struct sway_output *output = view->container->outputs->items[i]; ++ wlr_surface_for_each_surface(popup->popup_surface->surface, ++ iterator, output->wlr_output); ++ } ++} ++ ++static void handle_im_popup_map(struct wl_listener *listener, void *data) { ++ struct sway_input_popup *popup = ++ wl_container_of(listener, popup, popup_map); ++ input_popup_send_outputs(popup, surface_send_enter_iterator); ++ input_popup_update(popup); ++} ++ ++static void handle_im_popup_unmap(struct wl_listener *listener, void *data) { ++ struct sway_input_popup *popup = ++ wl_container_of(listener, popup, popup_unmap); ++ input_popup_send_outputs(popup, surface_send_leave_iterator); ++ input_popup_update(popup); ++} ++ ++static void handle_im_popup_destroy(struct wl_listener *listener, void *data) { ++ struct sway_input_popup *popup = ++ wl_container_of(listener, popup, popup_destroy); ++ wl_list_remove(&popup->focused_surface_unmap.link); ++ wl_list_remove(&popup->popup_surface_commit.link); ++ wl_list_remove(&popup->popup_destroy.link); ++ wl_list_remove(&popup->popup_unmap.link); ++ wl_list_remove(&popup->popup_map.link); ++ wl_list_remove(&popup->link); ++ free(popup); ++} ++ ++static void handle_im_popup_surface_commit(struct wl_listener *listener, ++ void *data) { ++ struct sway_input_popup *popup = ++ wl_container_of(listener, popup, popup_surface_commit); ++ input_popup_update(popup); ++} ++ ++static void handle_im_focused_surface_unmap( ++ struct wl_listener *listener, void *data) { ++ struct sway_input_popup *popup = ++ wl_container_of(listener, popup, focused_surface_unmap); ++ input_popup_update(popup); ++} ++ ++static void input_popup_set_focus(struct sway_input_popup *popup, ++ struct wlr_surface *surface) { ++ wl_list_remove(&popup->focused_surface_unmap.link); ++ ++ if (surface == NULL) { ++ wl_list_init(&popup->focused_surface_unmap.link); ++ input_popup_update(popup); ++ return; ++ } ++ struct wlr_layer_surface_v1 *layer_surface = ++ wlr_layer_surface_v1_try_from_wlr_surface(surface); ++ if (layer_surface != NULL) { ++ struct sway_layer_surface *layer = ++ layer_from_wlr_layer_surface_v1(layer_surface); ++ wl_signal_add( ++ &layer->layer_surface->surface->events.unmap, &popup->focused_surface_unmap); ++ input_popup_update(popup); ++ return; ++ } ++ ++ struct sway_view *view = view_from_wlr_surface(surface); ++ wl_signal_add(&view->events.unmap, &popup->focused_surface_unmap); ++ ++ // Since the focus has changed, the popup may have to adjust ++} ++ ++static void handle_im_new_popup_surface(struct wl_listener *listener, ++ void *data) { ++ struct sway_input_method_relay *relay = wl_container_of(listener, relay, ++ input_method_new_popup_surface); ++ struct sway_input_popup *popup = calloc(1, sizeof(*popup)); ++ popup->relay = relay; ++ popup->popup_surface = data; ++ popup->popup_surface->data = popup; ++ ++ wl_signal_add(&popup->popup_surface->surface->events.map, &popup->popup_map); ++ popup->popup_map.notify = handle_im_popup_map; ++ wl_signal_add( ++ &popup->popup_surface->surface->events.unmap, &popup->popup_unmap); ++ popup->popup_unmap.notify = handle_im_popup_unmap; ++ wl_signal_add( ++ &popup->popup_surface->events.destroy, &popup->popup_destroy); ++ popup->popup_destroy.notify = handle_im_popup_destroy; ++ wl_signal_add(&popup->popup_surface->surface->events.commit, ++ &popup->popup_surface_commit); ++ popup->popup_surface_commit.notify = handle_im_popup_surface_commit; ++ wl_list_init(&popup->focused_surface_unmap.link); ++ popup->focused_surface_unmap.notify = handle_im_focused_surface_unmap; ++ ++ struct sway_text_input *text_input = relay_get_focused_text_input(relay); ++ if (text_input != NULL) { ++ input_popup_set_focus(popup, text_input->input->focused_surface); ++ } else { ++ input_popup_set_focus(popup, NULL); ++ } ++ ++ wl_list_insert(&relay->input_popups, &popup->link); ++} ++ ++bool sway_input_popup_get_position( ++ struct sway_input_popup *popup, int *lx, int *ly) { ++ struct sway_text_input *text_input = ++ relay_get_focused_text_input(popup->relay); ++ if (text_input == NULL || text_input->input->focused_surface == NULL) { ++ *lx = 0; ++ *ly = 0; ++ return false; ++ } ++ ++ struct wlr_surface *focused_surface = text_input->input->focused_surface; ++ struct wlr_layer_surface_v1 *layer_surface = ++ wlr_layer_surface_v1_try_from_wlr_surface(focused_surface); ++ if (layer_surface != NULL) { ++ struct sway_layer_surface *layer = ++ layer_from_wlr_layer_surface_v1(layer_surface); ++ *lx = layer->geo.x + popup->x; ++ *ly = layer->geo.y + popup->y; ++ return true; ++ } ++ ++ ++ struct sway_view *view = view_from_wlr_surface( ++ text_input->input->focused_surface); ++ if (view->container == NULL || view == NULL) { ++ sway_log(SWAY_INFO, "Tried to find popup, but view is gone"); ++ return false; ++ } ++ *lx = view->container->surface_x - view->geometry.x + popup->x; ++ *ly = view->container->surface_y - view->geometry.y + popup->y; ++ return true; ++} ++ ++static void text_input_send_enter(struct sway_text_input *text_input, ++ struct wlr_surface *surface) { ++ wlr_text_input_v3_send_enter(text_input->input, surface); ++ struct sway_input_popup *popup; ++ wl_list_for_each(popup, &text_input->relay->input_popups, link) { ++ input_popup_set_focus(popup, surface); ++ } ++} ++ ++static void text_input_send_leave(struct sway_text_input *text_input, ++ struct wlr_surface *surface) { ++ wlr_text_input_v3_send_leave(text_input->input); ++ if (text_input->input->focused_surface == surface) { ++ struct sway_input_popup *popup; ++ wl_list_for_each(popup, &text_input->relay->input_popups, link) { ++ input_popup_set_focus(popup, NULL); ++ } ++ } ++} ++ + static void handle_im_commit(struct wl_listener *listener, void *data) { + struct sway_input_method_relay *relay = wl_container_of(listener, relay, + input_method_commit); +@@ -109,7 +438,7 @@ static void handle_im_destroy(struct wl_listener *listener, void *data) { + // the input method returns + text_input_set_pending_focused_surface(text_input, + text_input->input->focused_surface); +- wlr_text_input_v3_send_leave(text_input->input); ++ text_input_send_leave(text_input, text_input->input->focused_surface); + } + } + +@@ -133,8 +462,13 @@ static void relay_send_im_state(struct sway_input_method_relay *relay, + input->current.content_type.hint, + input->current.content_type.purpose); + } ++ struct sway_input_popup *popup; ++ wl_list_for_each(popup, &relay->input_popups, link) { ++ // send_text_input_rectangle is called in this function ++ input_popup_update(popup); ++ } + wlr_input_method_v2_send_done(input_method); +- // TODO: pass intent, display popup size ++ // TODO: pass intent + } + + static void handle_text_input_enable(struct wl_listener *listener, void *data) { +@@ -274,6 +608,9 @@ static void relay_handle_input_method(struct wl_listener *listener, + wl_signal_add(&relay->input_method->events.commit, + &relay->input_method_commit); + relay->input_method_commit.notify = handle_im_commit; ++ wl_signal_add(&relay->input_method->events.new_popup_surface, ++ &relay->input_method_new_popup_surface); ++ relay->input_method_new_popup_surface.notify = handle_im_new_popup_surface; + wl_signal_add(&relay->input_method->events.grab_keyboard, + &relay->input_method_grab_keyboard); + relay->input_method_grab_keyboard.notify = handle_im_grab_keyboard; +@@ -283,8 +620,7 @@ static void relay_handle_input_method(struct wl_listener *listener, + + struct sway_text_input *text_input = relay_get_focusable_text_input(relay); + if (text_input) { +- wlr_text_input_v3_send_enter(text_input->input, +- text_input->pending_focused_surface); ++ text_input_send_enter(text_input, text_input->pending_focused_surface); + text_input_set_pending_focused_surface(text_input, NULL); + } + } +@@ -293,6 +629,7 @@ void sway_input_method_relay_init(struct sway_seat *seat, + struct sway_input_method_relay *relay) { + relay->seat = seat; + wl_list_init(&relay->text_inputs); ++ wl_list_init(&relay->input_popups); + + relay->text_input_new.notify = relay_handle_text_input; + wl_signal_add(&server.text_input->events.text_input, +@@ -321,8 +658,9 @@ void sway_input_method_relay_set_focus(struct sway_input_method_relay *relay, + } else if (text_input->input->focused_surface) { + assert(text_input->pending_focused_surface == NULL); + if (surface != text_input->input->focused_surface) { ++ text_input_send_leave( ++ text_input, text_input->input->focused_surface); + relay_disable_text_input(relay, text_input); +- wlr_text_input_v3_send_leave(text_input->input); + } else { + sway_log(SWAY_DEBUG, "IM relay set_focus already focused"); + continue; +@@ -333,7 +671,7 @@ void sway_input_method_relay_set_focus(struct sway_input_method_relay *relay, + && wl_resource_get_client(text_input->input->resource) + == wl_resource_get_client(surface->resource)) { + if (relay->input_method) { +- wlr_text_input_v3_send_enter(text_input->input, surface); ++ text_input_send_enter(text_input, surface); + } else { + text_input_set_pending_focused_surface(text_input, surface); + } +diff --git a/sway/tree/container.c b/sway/tree/container.c +index d2c4ffc44c..37a45197d7 100644 +--- a/sway/tree/container.c ++++ b/sway/tree/container.c +@@ -392,6 +392,9 @@ static bool surface_is_popup(struct wlr_surface *surface) { + } + surface = subsurface->parent; + } ++ if (wlr_input_popup_surface_v2_try_from_wlr_surface(surface) != NULL) { ++ return true; ++ } + struct wlr_xdg_surface *xdg_surface = + wlr_xdg_surface_try_from_wlr_surface(surface); + return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP; +diff --git a/sway/tree/view.c b/sway/tree/view.c +index ec54fed81d..dd58bbcf85 100644 +--- a/sway/tree/view.c ++++ b/sway/tree/view.c +@@ -1208,6 +1208,9 @@ struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) { + if (wlr_layer_surface_v1_try_from_wlr_surface(wlr_surface) != NULL) { + return NULL; + } ++ if (wlr_input_popup_surface_v2_try_from_wlr_surface(wlr_surface) != NULL) { ++ return NULL; ++ } + + const char *role = wlr_surface->role ? wlr_surface->role->name : NULL; + sway_log(SWAY_DEBUG, "Surface of unknown type (role %s): %p", diff --git a/os/etc/portage/patches/mail-client/aerc/0001-templates-add-drop-function.patch b/os/etc/portage/patches/mail-client/aerc/0001-templates-add-drop-function.patch new file mode 100644 index 0000000..e8b9272 --- /dev/null +++ b/os/etc/portage/patches/mail-client/aerc/0001-templates-add-drop-function.patch @@ -0,0 +1,33 @@ +From 4e9853beda45fb31827a75aa094bd62568587c66 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Wed, 7 Jun 2023 14:51:08 +0900 +Subject: [PATCH] templates: add drop function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + lib/templates/functions.go | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/lib/templates/functions.go b/lib/templates/functions.go +index b331dc8..ffa6666 100644 +--- a/lib/templates/functions.go ++++ b/lib/templates/functions.go +@@ -304,4 +304,12 @@ var templateFuncs = template.FuncMap{ + "switch": switch_, + "case": case_, + "default": default_, ++ ++ "drop": drop, ++} ++ ++// drop removes an entry from the list of addresses ++func drop(sl []*mail.Address, idx int) []*mail.Address { ++ sl[idx] = sl[len(sl)-1] ++ return sl[:len(sl)-1] + } +-- +2.39.3 + diff --git a/os/etc/portage/patches/net-irc/senpai/0001-highlight-self.patch b/os/etc/portage/patches/net-irc/senpai/0001-highlight-self.patch new file mode 100644 index 0000000..df96172 --- /dev/null +++ b/os/etc/portage/patches/net-irc/senpai/0001-highlight-self.patch @@ -0,0 +1,32 @@ +From c7b5f7a645b926c5e26be2be2afd4a64b419fe38 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Tue, 25 Jul 2023 13:34:38 +0300 +Subject: [PATCH 1/2] highlight self +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + app.go | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/app.go b/app.go +index 1af68f8..ebb8fd2 100644 +--- a/app.go ++++ b/app.go +@@ -1376,6 +1376,11 @@ func (app *App) formatMessage(s *irc.Session, ev irc.MessageEvent) (buffer strin + headColor = ui.IdentColor(app.cfg.Colors.Nicks, head) + } + ++ if isFromSelf { ++ headColor = tcell.ColorWhite ++ hlLine = true ++ } ++ + var body ui.StyledStringBuilder + if isNotice { + color := ui.IdentColor(app.cfg.Colors.Nicks, ev.User) +-- +2.41.0 + diff --git a/os/etc/portage/patches/net-irc/senpai/0002-configure-highlight-self.patch b/os/etc/portage/patches/net-irc/senpai/0002-configure-highlight-self.patch new file mode 100644 index 0000000..7869de4 --- /dev/null +++ b/os/etc/portage/patches/net-irc/senpai/0002-configure-highlight-self.patch @@ -0,0 +1,83 @@ +From 5bbfa36fa8adb2b68973681e2fd363f882716b02 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Robert=20G=C3=BCnzler?= +Date: Tue, 25 Jul 2023 13:35:59 +0300 +Subject: [PATCH 2/2] configure highlight self +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Robert Günzler +--- + app.go | 4 ++-- + config.go | 8 ++++++++ + ui/ui.go | 1 + + 3 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/app.go b/app.go +index ebb8fd2..aeaed08 100644 +--- a/app.go ++++ b/app.go +@@ -1376,8 +1376,8 @@ func (app *App) formatMessage(s *irc.Session, ev irc.MessageEvent) (buffer strin + headColor = ui.IdentColor(app.cfg.Colors.Nicks, head) + } + +- if isFromSelf { +- headColor = tcell.ColorWhite ++ if isFromSelf && app.cfg.SelfEnabled { ++ headColor = app.cfg.Colors.Self + hlLine = true + } + +diff --git a/config.go b/config.go +index eb07d70..76dbdde 100644 +--- a/config.go ++++ b/config.go +@@ -71,6 +71,7 @@ type Config struct { + MemberColEnabled bool + TextMaxWidth int + StatusEnabled bool ++ SelfEnabled bool + + Colors ui.ConfigColors + +@@ -107,11 +108,13 @@ func Defaults() Config { + MemberColEnabled: true, + TextMaxWidth: 0, + StatusEnabled: true, ++ SelfEnabled: true, + Colors: ui.ConfigColors{ + Status: tcell.ColorGray, + Prompt: tcell.ColorDefault, + Unread: tcell.ColorDefault, + Nicks: ui.ColorSchemeBase, ++ Self: tcell.ColorDefault, + }, + Debug: false, + } +@@ -337,6 +340,11 @@ func unmarshal(filename string, cfg *Config) (err error) { + cfg.StatusEnabled = false + continue + } ++ case "self": ++ if colorStr == "disabled" { ++ cfg.SelfEnabled = false ++ continue ++ } + } + + var color tcell.Color +diff --git a/ui/ui.go b/ui/ui.go +index ab1c63f..d36b190 100644 +--- a/ui/ui.go ++++ b/ui/ui.go +@@ -28,6 +28,7 @@ type ConfigColors struct { + Prompt tcell.Color + Unread tcell.Color + Nicks ColorScheme ++ Self tcell.Color + } + + type UI struct { +-- +2.41.0 + diff --git a/os/etc/portage/patches/sys-libs/efivar/add-needed-fix.patch b/os/etc/portage/patches/sys-libs/efivar/add-needed-fix.patch new file mode 100644 index 0000000..f3fa196 --- /dev/null +++ b/os/etc/portage/patches/sys-libs/efivar/add-needed-fix.patch @@ -0,0 +1,28 @@ +diff --git a/src/include/defaults.mk b/src/include/defaults.mk +index ab8e9a8c..2c98e07d 100644 +--- a/src/include/defaults.mk ++++ b/src/include/defaults.mk +@@ -51,7 +51,6 @@ LDFLAGS ?= + override _CCLDFLAGS := $(CCLDFLAGS) + override _LDFLAGS := $(LDFLAGS) + override LDFLAGS = $(CFLAGS) -L. $(_LDFLAGS) $(_CCLDFLAGS) \ +- -Wl,--add-needed \ + -Wl,--build-id \ + -Wl,--no-allow-shlib-undefined \ + -Wl,--no-undefined-version \ +@@ -94,7 +93,6 @@ override _HOST_LDFLAGS := $(HOST_LDFLAGS) + override _HOST_CCLDFLAGS := $(HOST_CCLDFLAGS) + override HOST_LDFLAGS = $(HOST_CFLAGS) -L. \ + $(_HOST_LDFLAGS) $(_HOST_CCLDFLAGS) \ +- -Wl,--add-needed \ + -Wl,--build-id \ + -Wl,--no-allow-shlib-undefined \ + -Wl,-z,now \ +--- a/src/include/gcc.specs 2022-10-27 12:15:09.106855980 +0100 ++++ b/src/include/gcc.specs 2022-10-27 12:15:34.624091373 +0100 +@@ -5,4 +5,4 @@ + + %{!shared:%{!static:%{!r:-pie}}} %{static:-Wl,-no-fatal-warnings -Wl,-static -static -Wl,-z,relro,-z,now} -grecord-gcc-switches + + *link: +-+ --no-undefined-version --no-allow-shlib-undefined --add-needed -z now --build-id %{!static:%{!shared:-pie}} %{shared:-z relro} %{static:% +Date: Mon, 10 Oct 2022 14:22:36 -0400 +Subject: [PATCH] Revamp efi_well_known_* variable handling + +The current implementation attempts to use the linker to create aliases +for efi_well_known_guids and efi_well_known_names. It also tries to use +the linker to generate the variables efi_well_known_guids_end and +efi_well_known_names_end. + +When building with clang, the generated linker result results in a +broken libefivar.so that causes programs to segfault when linked against +it. This change does away with linker script hacker and instead +introduces pointers to store the locations of efi_well_known_guids_end +and efi_well_known_names_end. + +Additionally, efi_well_known_guids and efi_well_known_names are now +created as pointers that point to the beginning of their respective +arrays. + +Signed-off-by: Nicholas Vinson +Fixes: #234 +--- + src/Makefile | 7 ++-- + src/include/rules.mk | 5 +-- + src/include/workarounds.mk | 24 ------------- + src/makeguids.c | 72 +++++++++++++------------------------- + 4 files changed, 27 insertions(+), 81 deletions(-) + delete mode 100644 src/include/workarounds.mk + +diff --git a/src/Makefile b/src/Makefile +index e04357a7..ec1eabe6 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -4,7 +4,6 @@ include $(TOPDIR)/src/include/deprecated.mk + include $(TOPDIR)/src/include/version.mk + include $(TOPDIR)/src/include/rules.mk + include $(TOPDIR)/src/include/defaults.mk +-include $(TOPDIR)/src/include/workarounds.mk + + LIBTARGETS=libefivar.so libefiboot.so libefisec.so + STATICLIBTARGETS=libefivar.a libefiboot.a libefisec.a +@@ -30,7 +29,7 @@ EFISECDB_OBJECTS = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(EFISECDB_SOURCES))) + GENERATED_SOURCES = include/efivar/efivar-guids.h guid-symbols.c + MAKEGUIDS_SOURCES = makeguids.c util-makeguids.c + MAKEGUIDS_OBJECTS = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(MAKEGUIDS_SOURCES))) +-MAKEGUIDS_OUTPUT = $(GENERATED_SOURCES) guids.lds ++MAKEGUIDS_OUTPUT = $(GENERATED_SOURCES) + + util-makeguids.c : util.c + cp util.c util-makeguids.c +@@ -84,7 +83,7 @@ $(MAKEGUIDS_OUTPUT) : guids.txt + if [ "$${missing}" != "no" ]; then \ + exit 1 ; \ + fi +- ./makeguids $(LD_DASH_T) guids.txt guid-symbols.c include/efivar/efivar-guids.h guids.lds ++ ./makeguids guids.txt guid-symbols.c include/efivar/efivar-guids.h + + prep : makeguids $(GENERATED_SOURCES) + +@@ -96,7 +95,6 @@ libefivar.a : $(patsubst %.o,%.static.o,$(LIBEFIVAR_OBJECTS)) + libefivar.so : $(LIBEFIVAR_OBJECTS) + libefivar.so : | $(GENERATED_SOURCES) libefivar.map + libefivar.so : LIBS=dl +-libefivar.so : LDSCRIPTS=guids.lds + libefivar.so : MAP=libefivar.map + + efivar : $(EFIVAR_OBJECTS) | libefivar.so +@@ -137,7 +135,6 @@ deps : $(ALL_SOURCES) + clean : + @rm -rfv *~ *.o *.a *.E *.so *.so.* *.pc *.bin .*.d *.map \ + makeguids guid-symbols.c include/efivar/efivar-guids.h \ +- guids.lds \ + $(TARGETS) $(STATICTARGETS) + @# remove the deps files we used to create, as well. + @rm -rfv .*.P .*.h.P *.S.P include/efivar/.*.h.P +diff --git a/src/include/rules.mk b/src/include/rules.mk +index f309f863..8d0b68a2 100644 +--- a/src/include/rules.mk ++++ b/src/include/rules.mk +@@ -3,7 +3,6 @@ default : all + .PHONY: default all clean install test + + include $(TOPDIR)/src/include/version.mk +-include $(TOPDIR)/src/include/workarounds.mk + + comma:= , + empty:= +@@ -36,9 +35,7 @@ family = $(foreach FAMILY_SUFFIX,$(FAMILY_SUFFIXES),$($(1)_$(FAMILY_SUFFIX))) + $(CCLD) $(CCLDFLAGS) $(CPPFLAGS) -o $@ $(sort $^) $(LDLIBS) + + %.so : +- $(CCLD) $(CCLDFLAGS) $(CPPFLAGS) $(SOFLAGS) \ +- $(foreach LDS,$(LDSCRIPTS),$(LD_DASH_T) $(LDS)) \ +- -o $@ $^ $(LDLIBS) ++ $(CCLD) $(CCLDFLAGS) $(CPPFLAGS) $(SOFLAGS) -o $@ $^ $(LDLIBS) + ln -vfs $@ $@.1 + + %.abixml : %.so +diff --git a/src/include/workarounds.mk b/src/include/workarounds.mk +deleted file mode 100644 +index 57394edd..00000000 +--- a/src/include/workarounds.mk ++++ /dev/null +@@ -1,24 +0,0 @@ +-# SPDX-License-Identifier: SPDX-License-Identifier: LGPL-2.1-or-later +-# +-# workarounds.mk - workarounds for weird stuff behavior +- +-LD_FLAVOR := $(shell LC_ALL=C $(LD) --version | grep -E '^((.* )?LLD|GNU ld)'|sed 's/.* LLD/LLD/;s/ .*//g') +-LD_VERSION := $(shell LC_ALL=C $(LD) --version | grep -E '^((.* )?LLD|GNU ld)'|sed 's/.* LLD/LLD/;s/.* //') +-# 2.35 is definitely broken and 2.36 seems to work +-LD_DASH_T := $(shell \ +- if [ "x${LD_FLAVOR}" = xLLD ] ; then \ +- echo "" ; \ +- elif [ "x${LD_FLAVOR}" = xGNU ] ; then \ +- if echo "${LD_VERSION}" | grep -q -E '^2\.3[6789]|^2\.[456789]|^[3456789]|^[[:digit:]][[:digit:]]' ; then \ +- echo '-T' ; \ +- else \ +- echo "" ; \ +- fi ; \ +- else \ +- echo "Your linker ${LD_FLAVOR} version ${LD_VERSION} is not supported" ; \ +- exit 1 ; \ +- fi) +- +-export LD_DASH_T +- +-# vim:ft=make +diff --git a/src/makeguids.c b/src/makeguids.c +index 376bffba..bfdee12e 100644 +--- a/src/makeguids.c ++++ b/src/makeguids.c +@@ -107,51 +107,46 @@ write_guidnames(FILE *out, const char *listname, + gn->symbol, gn->name, gn->description); + } + fprintf(out, "};\n"); ++ fprintf(out, "const struct efivar_guidname\n" ++ "\t__attribute__((__visibility__ (\"default\")))\n" ++ "\t* const %s = %s_;\n", listname, listname); ++ fprintf(out, "const struct efivar_guidname\n" ++ "\t__attribute__((__visibility__ (\"default\")))\n" ++ "\t* const %s_end = %s_\n\t+ %zd;\n", ++ listname, listname, n - 1); + } + + int + main(int argc, char *argv[]) + { + int rc; +- int argstart = 0; +- FILE *symout, *header, *ldsout; +- int dash_t = 0; ++ FILE *symout, *header; + +- if (argc < 5) { ++ if (argc < 4) { + errx(1, "Not enough arguments.\n"); +- } else if (argc > 5 && !strcmp(argv[1],"-T")) { +- argstart = 1; +- dash_t = 1; +- } else if (argc > 5) { ++ } else if (argc > 4) { + errx(1, "Too many arguments.\n"); + } + +- symout = fopen(argv[argstart + 2], "w"); ++ symout = fopen(argv[2], "w"); + if (symout == NULL) +- err(1, "could not open \"%s\"", argv[argstart + 2]); +- rc = chmod(argv[argstart + 2], 0644); ++ err(1, "could not open \"%s\"", argv[2]); ++ rc = chmod(argv[2], 0644); + if (rc < 0) +- warn("chmod(%s, 0644)", argv[argstart + 2]); ++ warn("chmod(%s, 0644)", argv[2]); + +- header = fopen(argv[argstart + 3], "w"); ++ header = fopen(argv[3], "w"); + if (header == NULL) +- err(1, "could not open \"%s\"", argv[argstart + 3]); +- rc = chmod(argv[argstart + 3], 0644); +- if (rc < 0) +- warn("chmod(%s, 0644)", argv[argstart + 3]); +- +- ldsout = fopen(argv[argstart + 4], "w"); +- if (ldsout == NULL) +- err(1, "could not open \"%s\"", argv[argstart + 4]); +- rc = chmod(argv[argstart + 4], 0644); ++ err(1, "could not open \"%s\"", argv[3]); ++ rc = chmod(argv[3], 0644); + if (rc < 0) +- warn("chmod(%s, 0644)", argv[argstart + 4]); ++ warn("chmod(%s, 0644)", argv[3]); + + struct guidname_index *guidnames = NULL; + +- rc = read_guids_at(AT_FDCWD, argv[argstart + 1], &guidnames); ++ rc = read_guids_at(AT_FDCWD, argv[1], &guidnames); + if (rc < 0) +- err(1, "could not read \"%s\"", argv[argstart + 1]); ++ err(1, "could not read \"%s\"", argv[1]); + + struct efivar_guidname *outbuf; + +@@ -243,12 +238,11 @@ struct efivar_guidname {\n\ + fprintf(header, + "extern const struct efivar_guidname\n" + "\t__attribute__((__visibility__ (\"default\")))\n" +- "\tefi_well_known_guids[%d];\n", +- i); ++ "\t* const efi_well_known_guids;\n"); + fprintf(header, + "extern const struct efivar_guidname\n" + "\t__attribute__((__visibility__ (\"default\")))\n" +- "\tefi_well_known_guids_end;\n"); ++ "\t* const efi_well_known_guids_end;\n"); + fprintf(header, + "extern const uint64_t\n" + "\t__attribute__((__visibility__ (\"default\")))\n" +@@ -256,12 +250,11 @@ struct efivar_guidname {\n\ + fprintf(header, + "extern const struct efivar_guidname\n" + "\t__attribute__((__visibility__ (\"default\")))\n" +- "\tefi_well_known_names[%d];\n", +- i); ++ "\t* const efi_well_known_names;\n"); + fprintf(header, + "extern const struct efivar_guidname\n" + "\t__attribute__((__visibility__ (\"default\")))\n" +- "\tefi_well_known_names_end;\n"); ++ "\t* const efi_well_known_names_end;\n"); + fprintf(header, + "extern const uint64_t\n" + "\t__attribute__((__visibility__ (\"default\")))\n" +@@ -310,23 +303,6 @@ struct efivar_guidname {\n\ + + fclose(symout); + +- fprintf(ldsout, +- "SECTIONS\n" +- "{\n" +- " .data :\n" +- " {\n" +- " efi_well_known_guids = efi_well_known_guids_;\n" +- " efi_well_known_guids_end = efi_well_known_guids_ + %zd;\n" +- " efi_well_known_names = efi_well_known_names_;\n" +- " efi_well_known_names_end = efi_well_known_names_ + %zd;\n" +- " }\n" +- "}%s;\n", +- (line - 1) * sizeof(struct efivar_guidname), +- (line - 1) * sizeof(struct efivar_guidname), +- dash_t ? " INSERT AFTER .data" : ""); +- +- fclose(ldsout); +- + free(guidnames->strtab); + free(guidnames); + diff --git a/os/etc/portage/patches/sys-libs/llvm-libunwind/silence__unw_add_dynamic_fde.patch b/os/etc/portage/patches/sys-libs/llvm-libunwind/silence__unw_add_dynamic_fde.patch new file mode 100644 index 0000000..d31e1e2 --- /dev/null +++ b/os/etc/portage/patches/sys-libs/llvm-libunwind/silence__unw_add_dynamic_fde.patch @@ -0,0 +1,15 @@ +diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp +--- a/libunwind/src/libunwind.cpp ++++ b/libunwind/src/libunwind.cpp +@@ -296,9 +296,9 @@ + DwarfFDECache::add((LocalAddressSpace::pint_t)mh_group, + fdeInfo.pcStart, fdeInfo.pcEnd, + fdeInfo.fdeStart); + } else { +- _LIBUNWIND_DEBUG_LOG("__unw_add_dynamic_fde: bad fde: %s", message); ++ //_LIBUNWIND_DEBUG_LOG("__unw_add_dynamic_fde: bad fde: %s", message); + } + } + + /// IPI: for __deregister_frame() + diff --git a/os/etc/portage/patches/www-client/firefox/custom-pre-next-tab-shortcuts.patch b/os/etc/portage/patches/www-client/firefox/custom-pre-next-tab-shortcuts.patch new file mode 100644 index 0000000..30025db --- /dev/null +++ b/os/etc/portage/patches/www-client/firefox/custom-pre-next-tab-shortcuts.patch @@ -0,0 +1,13 @@ +--- a/browser/base/content/browser-sets.inc 2022-11-07 13:37:17.979518528 +0100 ++++ b/browser/base/content/browser-sets.inc 2022-11-07 13:37:11.128518819 +0100 +@@ -114,6 +114,10 @@ + #include ../../components/places/content/placesCommands.inc.xhtml + + ++ ++ ++ ++ +