From 2cd3883a2ce40470cebd9851b3f413fd07bfa45e Mon Sep 17 00:00:00 2001 From: Igor Teixeira Date: Tue, 20 Jan 2026 22:22:30 -0300 Subject: [PATCH 1/5] improve display protocol (x11 or wayland) detection --- pywal/wallpaper.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/pywal/wallpaper.py b/pywal/wallpaper.py index 11c1762..e93755d 100644 --- a/pywal/wallpaper.py +++ b/pywal/wallpaper.py @@ -44,6 +44,17 @@ def get_desktop_env(): return None +def detect_display_protocol(): + """Detect the active display protocol (X11 or Wayland).""" + if os.environ.get("WAYLAND_DISPLAY"): + return "wayland" + + if os.environ.get("DISPLAY") and not os.environ.get("WAYLAND_DISPLAY"): + return "x11" + + return None + + def xfconf(img): """Call xfconf to set the wallpaper on XFCE.""" xfconf_re = re.compile( @@ -72,8 +83,8 @@ def xfconf(img): def set_wm_wallpaper(img): """Set the wallpaper for non desktop environments.""" - session_type = os.getenv('XDG_SESSION_TYPE') - if session_type == "x11": + display_protocol = detect_display_protocol() + if display_protocol == "x11": # setters for x11 if shutil.which("feh"): util.disown(["feh", "--bg-fill", img]) @@ -100,7 +111,7 @@ def set_wm_wallpaper(img): logging.error("No wallpaper setter found.") return - elif session_type == "wayland": + elif display_protocol == "wayland": # setters for wayland if shutil.which("swww"): util.disown(["swww", "img", img]) @@ -118,16 +129,11 @@ def set_wm_wallpaper(img): return else: - if session_type: - logging.error( - "Wallpaper setting not supported for" - f" '{session_type}' session type." - ) - else: - logging.error("Cannot set wallpaper for this session.") logging.error( - "Check XDG_SESSION_TYPE is set correctly" - " only x11 and wayland session types are supported." + "Display protocol could not be determined. " + "Detection requires either WAYLAND_DISPLAY (for Wayland) " + "or DISPLAY (for X11) environment variables to be set. " + "Only x11 and wayland display protocols are supported." ) return From 3a06f3bfeebf5528767d84673f109e6f1c405b60 Mon Sep 17 00:00:00 2001 From: Igor Teixeira Date: Tue, 20 Jan 2026 22:28:26 -0300 Subject: [PATCH 2/5] Adapt info about XDG_SESSION_TYPE --- data/man/man1/wal.1 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/data/man/man1/wal.1 b/data/man/man1/wal.1 index 7a2919d..0a80407 100644 --- a/data/man/man1/wal.1 +++ b/data/man/man1/wal.1 @@ -219,8 +219,16 @@ under the same name. Using this feature you can also overwrite the default expor The section for other important information to using pywal16 that does not fit a specific section. .TP -.B "XDG_SESSION_TYPE" -This env var is needed to set the wallpaper when running an environment consisting of a standalone x11 window manager or wayland compositor, ie not a full blown desktop environment, for example something like the i3 window manager or the sway compositor, this is because some setup may have the packages for (in this example) BOTH i3 and sway, so in previous releases swaybg would be ran as wallpaper setter regardless of the user running i3 or sway, now we check this env var and follow the corresponding chain of possible wallpaper setters. +.B "DISPLAY, WAYLAND_DISPLAY" +These env vars are used to detect the active display protocol when setting the wallpaper in environments consisting of a standalone X11 window manager or Wayland compositor (i.e. not a full desktop environment). This avoids relying on +.B XDG_SESSION_TYPE +which may be set to "tty" on some setups (for example when starting X manually with startx). If +.B WAYLAND_DISPLAY +is set, pywal16 treats the session as Wayland. If +.B DISPLAY +is set (and +.B WAYLAND_DISPLAY +is not), pywal16 treats the session as X11. .TP .B "ImageMagick 7 Policy" From 318b98f6a4404411dfbce7e7e43d7c4e5762ff2c Mon Sep 17 00:00:00 2001 From: eylles Date: Wed, 21 Jan 2026 15:23:38 -0600 Subject: [PATCH 3/5] Use XDG_SESSION_TYPE, fallback to display protocol Re-Enable the XDG_SESSION_TYPE check as the primary way to detect if the session is x11 or wayland. If the XDG_SESSION_TYPE is not available try to detect the display protocol as a fallback. --- pywal/wallpaper.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/pywal/wallpaper.py b/pywal/wallpaper.py index e93755d..a54371d 100644 --- a/pywal/wallpaper.py +++ b/pywal/wallpaper.py @@ -83,8 +83,23 @@ def xfconf(img): def set_wm_wallpaper(img): """Set the wallpaper for non desktop environments.""" - display_protocol = detect_display_protocol() - if display_protocol == "x11": + session_type = os.getenv('XDG_SESSION_TYPE') + if not session_type: + logging.error( + "The XDG_SESSION_TYPE env var is not set " + "falling back to Display protocol detection." + ) + session_type = detect_display_protocol() + + if not session_type: + logging.error( + "Display protocol could not be determined. " + "Detection requires either WAYLAND_DISPLAY (for Wayland) " + "or DISPLAY (for X11) environment variables to be set. " + "Only x11 and wayland display protocols are supported." + ) + + if session_type == "x11": # setters for x11 if shutil.which("feh"): util.disown(["feh", "--bg-fill", img]) @@ -111,7 +126,7 @@ def set_wm_wallpaper(img): logging.error("No wallpaper setter found.") return - elif display_protocol == "wayland": + elif session_type == "wayland": # setters for wayland if shutil.which("swww"): util.disown(["swww", "img", img]) @@ -128,13 +143,14 @@ def set_wm_wallpaper(img): logging.error("No wallpaper setter found.") return - else: + elif session_type: logging.error( - "Display protocol could not be determined. " - "Detection requires either WAYLAND_DISPLAY (for Wayland) " - "or DISPLAY (for X11) environment variables to be set. " - "Only x11 and wayland display protocols are supported." - ) + "Wallpaper setting not supported for" + f" '{session_type}' session type." + ) + else: + logging.error("Cannot set wallpaper for this session.") + return From aedf9eb6e495a357a6bdd36138963cc67edb3f6e Mon Sep 17 00:00:00 2001 From: eylles Date: Wed, 21 Jan 2026 15:30:50 -0600 Subject: [PATCH 4/5] Remove trailing whitespace Yeh i unfortunately do care about the formatting this much. --- pywal/wallpaper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pywal/wallpaper.py b/pywal/wallpaper.py index a54371d..99fca99 100644 --- a/pywal/wallpaper.py +++ b/pywal/wallpaper.py @@ -48,10 +48,10 @@ def detect_display_protocol(): """Detect the active display protocol (X11 or Wayland).""" if os.environ.get("WAYLAND_DISPLAY"): return "wayland" - + if os.environ.get("DISPLAY") and not os.environ.get("WAYLAND_DISPLAY"): return "x11" - + return None From 9b5207b5533dca73f0f320709c8ab48198082e9d Mon Sep 17 00:00:00 2001 From: eylles Date: Wed, 21 Jan 2026 17:04:00 -0600 Subject: [PATCH 5/5] Re-Add XDG_SESSION_TYPE info Also re-structure the information to be (hopefully) easier to read. --- data/man/man1/wal.1 | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/data/man/man1/wal.1 b/data/man/man1/wal.1 index 0a80407..d42fc11 100644 --- a/data/man/man1/wal.1 +++ b/data/man/man1/wal.1 @@ -219,16 +219,27 @@ under the same name. Using this feature you can also overwrite the default expor The section for other important information to using pywal16 that does not fit a specific section. .TP -.B "DISPLAY, WAYLAND_DISPLAY" -These env vars are used to detect the active display protocol when setting the wallpaper in environments consisting of a standalone X11 window manager or Wayland compositor (i.e. not a full desktop environment). This avoids relying on +.B "XDG_SESSION_TYPE, DISPLAY, WAYLAND_DISPLAY" +The .B XDG_SESSION_TYPE -which may be set to "tty" on some setups (for example when starting X manually with startx). If +env var is needed to set the wallpaper when running an environment consisting of a standalone x11 window manager or wayland compositor (i.e. not a full desktop environment). +If +.B XDG_SESSION_TYPE +is not available the +.B DISPLAY +and .B WAYLAND_DISPLAY -is set, pywal16 treats the session as Wayland. If +vars are used as fallback to detect the active display protocol. This avoids relying only on +.B XDG_SESSION_TYPE +which may be set to "tty" on some setups (for example when starting X manually with startx) or not set at all. If +.B WAYLAND_DISPLAY +is set, the session is treated as Wayland. If .B DISPLAY is set (and .B WAYLAND_DISPLAY -is not), pywal16 treats the session as X11. +is not), the session is treated as X11. + +This is necessary because some setup may have the packages for (example) BOTH i3 and sway, so in previous releases swaybg had priority over feh and would be ran as wallpaper setter regardless of the user currently running i3 or sway, these checks allow us to follow the corresponding chain of possible wallpaper setters. .TP .B "ImageMagick 7 Policy"