Troubleshooting launching xfce/any session on live ISO

I just want to sincerely thank all those involved in fixing this issue, well done! I wish I could have helped more, but I got buried with work and and just did not have any spare time. But I would watch the thread on my phone when I could, and I learned a lot! Any way, I hope to do some testing on my ISO’s this weekend, Thank you all again!

Cheers,
João

2 Likes

Hi guys! I just go back and tested more today.

-=202607220620=-

manjaro-xfce-26.1-testing-minimal-260722-linux618.iso

Old laptop bios mode:
Default mode logs in kb hun

grub2 mode logs in, kb engrish.


Desktop UEFI:

Default logs in kb HUN

grub2 mode logs in, kb engrish

manjaro-generic-oem-kde-26.1-testing-260722-linux618.iso

OLD laptop bios:
default logs in kb layout engrish

grub2 logs in kb layout engrish


Desktop uefi:

default logs in kb layout engrish

grub2 mode behaves the same

manjaro-generic-oem-gnome-26.1-testing-260722-linux618.iso

OLD laptop bios mode:

default logs in, kb layout engrish

grub2 logs in, db layout engrish


Desktop UEFI:

default logs in, kb layout engrish
Same in grub2 mode

The grub2 mode is a Ventoy specific mode - completely unrelated to Manjaro ISO boot.

The Ventoy grub2 mode is only useful if Ventoy’s default mode will not boot.

This mode is a last resort when using Ventoy as the ISO listing loader.

2 Likes

Can i ask what should be the official testing method to create pendrive, or acceptable testing method? Should use the gnome disk tool? balena etcher, rufus?
And what info will be usefull/valuable?

grub2boot . Ventoy

About GRUB2 Mode

Use GRUB2 mode only when you run into problem with the default mode.

GRUB2 mode does not overwrite changes to locale parameters

Boot parameters can be edited by using E

1 Like

Technically - the ISO should be used as-is - how exactly that translates into real world depends on how you handle your storage medium.

Grub offers the option to boot the ISO by reading the ISO directly from disk.

The only method that do not work - ever - is the iso-mode originally used by Rufus and claimed as the only way. After contacting Manjaro - the Rufus developer changed how a Manjaro ISO is written to be a byte-to-byte copy - known in Rufus as dd-mode (the actual documentation has been lost to the byte-void).

That means - any software capable of doing a byte-to-byte copy will work.

As Grub - usually - is capable of booting the ISO directly, Ventoy is widely accepted and so is the more manual approach as it has been described in [root tip] [How To] Multi ISO USB with storage partition.

One could say that creating a byte-to-byte copy of a Manjaro ISO, to the chosen target medium should prove without any shred of doubt that the ISO is bootable and fully functional.

I do want to add that one should always use a suitable USB-stick, as using a DVD is discouraged as the loading of the desktop may be unreasonable slow, thereby causing a bad experience.

2 Likes

Any method that creates an exact “byte-for-byte” (as @linux-aarhus suggests) copy of an ISO should normally suffice.

Ventoy is popular because once the USB is created, one only needs to drag an ISO file to the empty Ventoy USB partition (the actual Ventoy functionality remains contained within the $ESP of the USB).

Each of us have preferences; opinions; however, for the convenience factor (being able to store many ISO files on the Ventoy USB, ready to boot) my goto is Ventoy.

3 Likes

You could make an USB drive with three partitions: EFI, GRUB, and a data partition for ISO-files.
I doubt if this is able to boot a Windows install ISO like Ventoy can, but I never need that anyway.

grub2usb.sh: script to make partitions
#!/bin/sh

# inspired by colinxu.wordpress.com/2018/12/29/create-a-universal-bootable-usb-drive-using-grub2/
THIS=$(realpath --canonicalize-existing "$0" 2>/dev/null)
THISPATH=$(dirname "$THIS")
THISPROG=$(basename $THIS)
efilabel=EFIPART
fstype=ext2
datalabel=ISOSHERE

HELPTXT="\t run $THIS -h for help\n"
USAGE="
 $THISPROG wipes a device and installs GRUB2

 Usage: $THISPROG [options] {device}
 options:
 -l {label} : label for data partition, default $datalabel
 -t {vfat|exfat|ext2|ext4} : type of file system to use, default $fstype
 -v: verbose mode, show commands
 -d: DEBUG mode, just show commands, do not run commands

 $THISPROG must be run by root or with sudo
"
#################### FUNCTIONS #################################################

Exit_if_Error ()
# $1 is return code to test
# $2 is command line that returned return code
{
    if test $1 -ne 0 ; then
        printf %b "\n$(date '+%F %T') command '$2' failed with return code $1\n"
        umount  ${DEVICE}1 ${DEVICE}2 ${DEVICE}3
        exit $1
    fi
}

MakeFilesys ()
# $1 is file system type
# $2 is device to create file system on
# $3 is label for file system (optional)
{
    local _fsopt _command
    if test "$1" = "ext4" -o "$1" = "ext2" ; then _fsopt='-m 0' ; fi
    if test -z "$3" ; then
        _command="mkfs $VERBOSE $_fsopt -t $1 $2"
    else
        _command="mkfs $VERBOSE $_fsopt -t $1 -L $3 $2"
    fi
    if test -n "$VERBOSE" ; then printf %b "\nmaking file system with $_command\n" ; fi
    $DEBUG $_command  ;  Exit_if_Error $? "$_command"
} # MakeFilesys

#################### MAIN ######################################################

unset DEBUG  VERBOSE  VERB
while getopts 'l:t:vdhH' OPTION ; do
    case $OPTION in
    l)  datalabel=$OPTARG  ;;   # no blanks allowed
    t)
        fstype=$OPTARG
        if test $fstype = fat -o $fstype = msdos -o $fstype = umsdos ;  then fstype=vfat ; fi
        if test $fstype != vfat -a $fstype != exfat -a $fstype != ext2 -a $fstype != ext4 ; then
            printf %b "\n\t filesystem must be vfat or exfat or ext2 or ext4 - ABORTING\n$HELPTXT"
            exit 1
        fi
    ;;
    v)  VERBOSE='--verbose' ; VERB='-v'  ;;
    d)  DEBUG='echo -e \nDEBUG ECHOING' ; VERBOSE='--verbose' ; VERB='-v'  ;;
    *)
        printf %b "$USAGE"
        exit 1
    ;;
    esac
done
shift $(expr $OPTIND - 1)
if test -n "$VERBOSE" ; then printf %b "\n$THIS started $(date '+%F %T') with PID $$ and parameters '$*'\n" ; fi

if test $# -ne 1 ; then printf %b "\n\t No device in parameters - ABORTING!\n$USAGE" ; exit 1
else DEVICE="$1"
fi

devtype=$(lsblk -ndo type ${DEVICE}) ; rescode=$?
if test $rescode -gt 0  ; then printf %b "\n\t $DEVICE is not a usable device - ABORTING!\n$HELPTXT" ; exit 2
elif test "$devtype" = "part" ; then printf %b "\n\t $DEVICE is a partition, you must use disk device - ABORTING!\n$HELPTXT" ; exit 3
elif test "$devtype" != "disk" ; then printf %b "\n\t $DEVICE is not a disk - ABORTING!\n$HELPTXT" ; exit 4
fi

printf %b "\n\t THIS SCRIPT WILL ERASE EVERYTHING ON $DEVICE COMPLETELY \n\t enter YES to proceed or press Ctrl+C to abort - LAST CHANCE !\n"
read pressedkey
if test "$pressedkey" != "YES" ; then printf %b "\n\t did not enter YES - ABORTING!\n" ; exit 1 ; fi

printf %b "\n\t Creating partitions and install GRUB2 on '$DEVICE' , file system '$fstype' with label '${datalabel}'\n"

if test $(id -u) -gt 0 ; then printf %b "\n\t YOU ARE NOT ROOT - ABORTING!\n$HELPTXT" ; exit 9 ; fi

if test -n "$VERBOSE" -a -z "$DEBUG" ; then set -x ; fi

$DEBUG umount ${DEVICE}1 ${DEVICE}2 ${DEVICE}3

# remove all file systems on device
$DEBUG wipefs --all ${DEVICE}
$DEBUG sgdisk --zap-all
$DEBUG dd if=/dev/zero of=${DEVICE} bs=4k count=64
sleep 1
partprobe ${DEVICE}

# Create 1st partition as BIOS Boot partition to store MBR boot code
$DEBUG sgdisk --new=1:2048:4095  --typecode=1:0xEF02 ${DEVICE}
# Hide BIOS boot partition from EFI and mark it bootable
$DEBUG sgdisk --attributes=1:set:1 --attributes=1:set:2 ${DEVICE}
# Create 2nd partition as ESP for UEFI boot code
$DEBUG sgdisk --new=2:4096:135167  --typecode=2:0xEF00 ${DEVICE}
# Create partition for ISO-files etc.
$DEBUG sgdisk --largest-new=3  ${DEVICE}

$DEBUG mkfs.vfat -F32 -n ${efilabel} ${DEVICE}2
$DEBUG umount ${DEVICE}1 ${DEVICE}2 ${DEVICE}3
MakeFilesys $fstype ${DEVICE}3 ${datalabel}
partprobe ${DEVICE}

mkdir --parent /mnt/efi /mnt/data
$DEBUG mount ${DEVICE}2 /mnt/efi
$DEBUG grub-install --target=i386-pc --boot-directory=/mnt/efi/boot --removable ${DEVICE}
$DEBUG grub-install --target=i386-efi --efi-directory=/mnt/efi/ --boot-directory=/mnt/efi/boot --removable ${DEVICE}
$DEBUG grub-install --target=x86_64-efi --efi-directory=/mnt/efi/ --boot-directory=/mnt/efi/boot --removable ${DEVICE}
if test -r "$THISPATH/usbgrub.cfg" ; then $DEBUG cp --preserve=timestamps "$THISPATH/usbgrub.cfg" /mnt/efi/boot/grub/grub.cfg ; fi
if test -r "$THISPATH/menu.autoiso.sh" ; then
    $DEBUG cp --preserve=timestamps "$THISPATH/menu.autoiso.sh" /mnt/efi/boot/grub/
    $DEBUG mount ${DEVICE}3 /mnt/data
    $DEBUG mkdir /mnt/data/ISOboot
    $DEBUG chown 1000:1000 /mnt/data/ISOboot
fi

umount  ${DEVICE}1 ${DEVICE}2 ${DEVICE}3
menu.autoiso.sh: GRUB script to boot from ISO
########## Auto Live ISO distros searching below ###############################

if test -z "$langcode" ; then langcode=dk ; fi    # must set global variable
insmod regexp

function basename { regexp -s 1:"$2" '.*/([^/]*)$' "$1"; }

function increment {
# stackoverflow.com/questions/42244685/grub2-howto-increment-variable
# increment number
# increment $varname -s varname
    # Validate arguments
    [ $# -eq 1 -o $# -eq 3 ]
    set usage=$?
    if [ $# -eq 3 ]; then
        [ "$2" = "-s" -o "$2" = "--set" ]
        set usage=$?
    fi
    if [ $usage -eq 1 -o "$1" = "-h" -o "$1" = "--help" ]; then
        echo "Usage: increment NUMBER"
        echo "Increment decimal NUMBER >= 0."
        echo
        echo "-s, --set VARNAME  Store value in VARNAME."
        unset usage
        return 1
    fi
    unset usage
    # Validate decimal number >= 0 (empty string "" equivalent to 0)
    if ! regexp '^[0-9]*$' -- "$1"; then
        echo "$1: not a decimal number >=0 "
        return 1
    fi
    # Use regexp to compute and save $1 (mod 10) to (div, mod)
    # Use tr to obtain successor(mod) where "0" requires carry
    if [ -z "$1" ]; then
        set div=
        set mod=0
    else
        regexp '(.*)([0-9])$' "$1" -s 1:div -s 2:mod
    fi
    tr '[0123456789]' '[1234567890]' "$mod" -s successor
    # Work right to left adding a zero for each carry
    set zeros=
    while [ -n "$div" -a "$successor" = "0" ]; do
        set zeros=0${zeros}
        regexp '(.*)([0-9])$' "$div" -s 1:div -s 2:mod
        tr '[0123456789]' '[1234567890]' "$mod" -s successor
    done
    if [ "$successor" = "0" ]; then
        set successor=10
    fi
    # Remove leading zeros
    set result=${div}${successor}${zeros}
    regexp '^00*(..*)$' "$result" -s result
    # Save or print result
    if [ -n "$3" ]; then
        eval set $3=${result}
    else
        echo ${result}
    fi
    # Cleanup function variables
    for varname in div mod successor zeros result; do
        eval unset $varname
    done
    unset varname
} # increment

# https://github.com/cfriedt/grub/blob/master/docs/autoiso.cfg
# https://gitlab.com/linux-be/grub/blob/master/docs/autoiso.cfg
# and from source in https://ftp.gnu.org/gnu/grub/

# Sample GRUB script to autodetect operating systems
#
# Copyright (C) 2010  Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.

function pathname { regexp -s 2:"$2" '^(\(.*\))?(/.*)$' "$1"; }
function devname  { regexp -s "$2" '^(\(.*\)).*$' "$1"; }

function loopback_iso_entry {
    realdev="$1"
    isopath="$2"
    loopdev="$3"

    if test -f /boot/grub/loopback.cfg; then
        cfgpath=/boot/grub/loopback.cfg
    elif test -f /grub/loopback.cfg; then
        cfgpath=/grub/loopback.cfg
    elif test -f /boot/grub2/loopback.cfg; then
        cfgpath=/boot/grub2/loopback.cfg
    elif test -f /grub2/loopback.cfg; then
        cfgpath=/grub2/loopback.cfg
    else
        return 1;
    fi

#     echo loopback.cfg $isopath: yes
#     menuentry "Boot GRUB Loopback Config from ${realdev}${isopath}" "$realdev" "$isopath" "$cfgpath" {
#     echo "loopback.cfg $isopath: yes - press escape to continue" ; sleep --verbose --interruptible 5
    basename ${isopath} isofile
    menuentry "$foundcount: ${isofile} GRUB Loopback Config ${realdev}" "$realdev" "$isopath" "$cfgpath" --hotkey="$foundcount" {
        set device="$2"
        set iso_path="$3"
        set cfg_path="$4"

        export iso_path
        loopback loopdev_cfg "${device}${iso_path}"
        set root=(loopdev_cfg)
        configfile $cfg_path
        loopback -d loopdev_cfg
    }
    return 0
} # loopback_iso_entry


function casper_iso_entry {
    realpath="$1"
    isopath="$2"
    loopdev="$3"

    if ! test -f /casper/vmlinuz; then return 1; fi
    initrd=
#    for f in /casper/initrd.*z; do
    for f in /casper/initrd* ; do
        if ! test -f "$f"; then continue; fi
        pathname "$f" initrd
    done
    if test -z "$initrd"; then return 1; fi

#     echo casper $isopath: yes
#     menuentry "Casper based Linux from ${realdev}${isopath}" "$realdev" "$isopath" "$initrd" {
#     echo "casper $isopath: yes - press escape to continue" ; sleep --verbose --interruptible 5
    basename ${isopath} isofile
    menuentry "$foundcount: ${isofile} Casper based ${realdev}" "$realdev" "$isopath" "$initrd" --hotkey="$foundcount" {
        set device="$2"
        set isopath="$3"
        set initrd="$4"

        loopback loopdev_casper "${device}${isopath}"
        set root=(loopdev_casper)
        linux /casper/vmlinuz boot=casper iso-scan/filename="$isopath" quiet splash noprompt keyb="$langcode" \
            debian-installer/language="$langcode" console-setup/layoutcode?="$langcode" --
        initrd $initrd
        loopback -d loopdev_casper
    }
    return 0
} # casper_iso_entry

########## functions added by Freddy Vejen below ###############################

function tails_iso_entry {
    realdev="$1"
    isopath="$2"

    if ! test ( -f /live/Tails.module -a -f /live/vmlinuz -a -f /live/initrd.img ) ; then return 1; fi

#     echo "TAILS in ${realdev}${isopath} : yes - press escape to continue" ; sleep --verbose --interruptible 5
    menuentry "$foundcount: TAILS in ${realdev}${isopath}" "$realdev" "$isopath" --hotkey="$foundcount" {
        set device="$2"
        set iso_path="$3"

        set kernel=/live/vmlinuz
        set initramdisk=/live/initrd.img

        loopback looplocal "${device}${iso_path}"
        set root=(looplocal)
        set FAILSAFE="noapic noapm nodma nomce nolapic nomodeset nosmp vga=normal"
        echo    "Loading kernel $kernel ..."
        linux   $kernel     findiso=$iso_path boot=live config nopersistence noprompt timezone=Europe/Copenhagen nosplash noautologin module=Tails slab_nomerge slub_debug=FZ mce=0 vsyscall=none init_on_free=1 mds=full,nosmt page_alloc.shuffle=1 randomize_kstack_offset=on efi_pstore.pstore_disable=1 erst_disable spec_store_bypass_disable=on systemd.condition_needs_update=no
#   linux /live/vmlinuz initrd=/live/initrd.img boot=live config live-media=removable nopersistence noprompt timezone=Etc/UTC splash noautologin module=Tails slab_nomerge slub_debug=FZ mce=0 vsyscall=none init_on_free=1 mds=full,nosmt page_alloc.shuffle=1 randomize_kstack_offset=on efi_pstore.pstore_disable=1 erst_disable spec_store_bypass_disable=on systemd.condition_needs_update=no FSUUID=${rootuuid} quiet
        echo    'Loading initial ramdisk ...'
        initrd  $initramdisk
        loopback -d looplocal
    } # end of menuentry
    return 0
} # tails_iso_entry


function clozil_iso_entry {
    realdev="$1"
    isopath="$2"

    if ! test ( -f /live/Clonezilla-Live-Version -a -f /live/vmlinuz -a -f /live/initrd.img ) ; then return 1; fi

#     echo "Clonezilla in ${realdev}${isopath} : yes - press escape to continue" ; sleep --verbose --interruptible 5
    basename ${isopath} isofile
    menuentry "$foundcount: ${isofile} Clonezilla ${realdev}" "$realdev" "$isopath" --hotkey="$foundcount" {
        set device="$2"
        set iso_path="$3"

        set kernel=/live/vmlinuz
        set initramdisk=/live/initrd.img

        loopback looplocal "${device}${iso_path}"
        set root=(looplocal)
        echo        "Loading kernel $kernel ... "
# failsafe from iso/boot/grub/grub.cfg # linux $kernel boot=live union=overlay username=user config components loglevel=3 hostname=cl-3.3.2-31 noswap edd=on nomodeset enforcing=0 locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch="no" acpi=off irqpoll noapic noapm nodma nomce nolapic nosmp net.ifnames=0 nomodeset vga=normal nosplash
        linux       $kernel    boot=live findiso=$iso_path locales=en_US.UTF-8 keyboard-layouts=$langcode nosplash noswap vga=normal
        echo        'Loading initial ramdisk ...'
        initrd      $initramdisk
        loopback -d looplocal
    } # end of menuentry
    return 0
} # clozil_iso_entry


function live_iso_entry {
    realdev="$1"
    isopath="$2"

    if ! test ( -f /live/vmlinuz -a -f /live/initrd.img ) ; then return 1; fi

#     echo "UNKNOWN possible Live distro in ${realdev}${isopath} : yes - press escape to continue" ; sleep --verbose --interruptible 5
    basename ${isopath} isofile
    menuentry "$foundcount: ${isofile} UNKNOWN ${realdev}" "$realdev" "$isopath" --hotkey="$foundcount" {
        set device="$2"
        set iso_path="$3"

        set kernel=/live/vmlinuz
        set initramdisk=/live/initrd.img

        loopback looplocal "${device}${iso_path}"
        set root=(looplocal)
        echo        "Loading kernel $kernel ..."
        linux       $kernel    boot=live findiso=$iso_path locales=en_US.UTF-8 keyboard-layouts=$langcode nosplash noswap
        echo        'Loading initial ramdisk ...'
        initrd      $initramdisk
        loopback -d looplocal
    } # end of menuentry
    return 0
} # live_iso_entry

########## functions added by Freddy Vejen above ###############################

function scan_isos {
    isodirs="$1"
    echo "scan_isos '$isodirs' "

    for device in (*) ; do echo "device '$device'" ; done    # try to wake up devices
    foundcount=0
    for dev in (*); do
        for dir in $isodirs; do    # NB: all isodirs must have trailing slash
            for file in ${dev}${dir}*.iso ${dev}${dir}*.ISO ${dev}${dir}*.isodef ; do
                if ! test -f "$file"; then continue; fi # reloop if not file
# echo "foundcount '$foundcount'  dev '$dev'  isopath '$isopath' "
# echo "- press escape to continue" ; sleep --verbose --interruptible 5
                pathname $file isopath
                if test -z "$dev" -o -z "$isopath"; then continue; fi # reloop if empty

                if ! loopback loopdev_scan "$file"; then continue; fi # reloop if loop mount fails
                saved_root=$root
                set root=(loopdev_scan)
# entries with (loopdev_scan) are from GRUB's autoiso.cfg
                if   clozil_iso_entry   $dev $isopath ; then increment $foundcount -s foundcount
                elif tails_iso_entry    $dev $isopath ; then increment $foundcount -s foundcount
                elif casper_iso_entry   $dev $isopath (loopdev_scan); then increment $foundcount -s foundcount      # Ubuntu uses GRUB loop-back to point to Casper
                elif loopback_iso_entry $dev $isopath (loopdev_scan); then increment $foundcount -s foundcount
# NB: loopback_iso_entry must be after all the specific distros because it catches all with *grub/loopback.cfg
                elif live_iso_entry     $dev $isopath ; then increment $foundcount -s foundcount
# NB: live_iso_entry must be last because it does not check for file with certain file name that can identify distro
                else true; fi
echo ' '
                set root=$saved_root
                loopback -d loopdev_scan
            done # for file
        done # for dir
    done # for dev
# echo "end of scan_isos - press escape to continue" ; sleep --verbose --interruptible 30
    return 0
} # scan_isos

########## Auto Live ISO MAIN ##################################################

# echo "before scan_isos - press escape to continue" ; sleep --verbose --interruptible 5
# NB: all isodirs must have trailing slash
  scan_isos "/ /*iso*/ /boot/*iso*/ /*Iso*/ /boot/*Iso*/ /*ISO*/ /BOOT/*ISO*/ /_ISO/LINUX/ "
# echo "after scan_isos - press escape to continue" ; sleep --verbose --interruptible 5

########## Auto Live ISO distros searching above ###############################

usbgrub.cfg: GRUB config file


insmod part_gpt # GPT partition table
insmod part_msdos # MBR partition table
insmod fat # FAT partition
insmod exfat # exFAT partition
insmod ext2 # ext partition
insmod ntfs # NTFS partition
insmod ntfscomp # NTFS compression
insmod allvideo # Additional video and graphics
insmod chain # chainloader

if [ ${grub_platform} == "pc" ]; then
    insmod ntldr # chainloader from file without reading boot record
else
    insmod efi_uga # UEFI UGA
    insmod efi_gop # UEFI GOP
fi

if [ -s $prefix/grubenv ]; then
  load_env
fi

set timeout_style=menu
play 480 440 1

menuentry "Reboot" {
    reboot
}

menuentry "Shutdown" {
    halt
}

submenu 'L: LIVE menu - search for ISO files with live distros' --hotkey=L {configfile $prefix/menu.autoiso.sh}
3 Likes

There are many ways to achieve a similar goal; for a “Grub2-only” approach, there is this solution which could be written to CD, or to a (small) USB, or simply dragged to a Ventoy USB: :slight_smile:

1 Like

please somene push this to manjaro-tools-livecd
I only can test on Gnome. Works good!

lib/util-live.sh:

#!/bin/bash
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

kernel_cmdline(){
	for param in $(cat /proc/cmdline); do
		case "${param}" in
			$1=*) echo "${param##*=}"; return 0 ;;
			$1) return 0 ;;
			*) continue ;;
		esac
	done
	[ -n "${2}" ] && echo "${2}"
	return 1
}

get_lang(){
	echo $(kernel_cmdline lang)
}

get_keytable(){
	echo $(kernel_cmdline keytable)
}

get_tz(){
	echo $(kernel_cmdline tz)
}

get_timer_ms(){
	echo $(date +%s%3N)
}

# $1: start timer
elapsed_time_ms(){
	echo $(echo $1 $(get_timer_ms) | awk '{ printf "%0.3f",($2-$1)/1000 }')
}

load_live_config(){

	[[ -f $1 ]] || return 1

	live_conf="$1"

	[[ -r ${live_conf} ]] && source ${live_conf}

	[[ -z ${autologin} ]] && autologin=true

	[[ -z ${username} ]] && username="manjaro"

	[[ -z ${password} ]] && password="manjaro"

	[[ -z ${addgroups} ]] && addgroups=""

	[[ -z ${login_shell} ]] && login_shell="/bin/bash"

	[[ -z ${smb_workgroup} ]] && smb_workgroup="Manjaro"

	echo "Loaded ${live_conf}: $(elapsed_time_ms ${livetimer})ms" >> /var/log/manjaro-live.log

	return 0
}

is_valid_de(){
	if [[ ${default_desktop_executable} != "none" ]] && \
	[[ ${default_desktop_file} != "none" ]]; then
		return 0
	else
		return 1
	fi
}

load_desktop_map(){
    local _space="s| ||g" _clean=':a;N;$!ba;s/\n/ /g' _com_rm="s|#.*||g" \
        file=${DATADIR}/desktop.map
    local desktop_map=$(sed "$_com_rm" "$file" \
            | sed "$_space" \
            | sed "$_clean")
    echo ${desktop_map}
}

detect_desktop_env(){
    local xs=/usr/share/xsessions ex=/usr/bin key val map=( $(load_desktop_map) )
    default_desktop_file="none"
    default_desktop_executable="none"
    for item in "${map[@]}";do
        key=${item%:*}
        val=${item#*:}
        if [[ -f $xs/$key.desktop ]] && [[ -f $ex/$val ]];then
            default_desktop_file="$key"
            default_desktop_executable="$val"
        fi
    done
}

configure_accountsservice(){
	local path=/var/lib/AccountsService/users
	if [ -d "${path}" ] ; then
		echo "[User]" > ${path}/$1
		echo "XSession=${default_desktop_file}" >> ${path}/$1
		if [[ -f "/var/lib/AccountsService/icons/$1.png" ]];then
			echo "Icon=file:///var/lib/AccountsService/icons/$1.png" >> ${path}/$1
		fi
	fi
}

 set_lightdm_greeter(){
	local greeters=$(ls /usr/share/xgreeters/*greeter.desktop) name
	for g in ${greeters[@]};do
		name=${g##*/}
		name=${name%%.*}
		case ${name} in
			lightdm-gtk-greeter) break ;;
			lightdm-*-greeter)
				sed -i -e "s/^.*greeter-session=.*/greeter-session=${name}/" /etc/lightdm/lightdm.conf
			;;
		esac
	done
 }

 set_lightdm_vt(){
	sed -i -e 's/^.*minimum-vt=.*/minimum-vt=7/' /etc/lightdm/lightdm.conf
 }

# set_sddm_elogind(){
#     gpasswd -a sddm video &> /dev/null
# }

set_pam(){
    for conf in /etc/pam.d/*;do
        sed -e 's|systemd.so|elogind.so|g' -i $conf
    done
}

configure_samba(){
    local conf=/etc/samba/smb.conf
    cp /etc/samba/smb.conf.default $conf
    sed -e "s|^.*workgroup =.*|workgroup = ${smb_workgroup}|" -i $conf
}

configure_displaymanager(){
	# Try to detect desktop environment
	# Configure display manager
	if [[ -f /usr/bin/lightdm ]];then
		groupadd -r autologin
		[[ -d /run/openrc ]] && set_lightdm_vt
		set_lightdm_greeter
		if $(is_valid_de); then
			sed -i -e "s/^.*user-session=.*/user-session=$default_desktop_file/" /etc/lightdm/lightdm.conf
		fi
		if ${autologin};then
			gpasswd -a ${username} autologin &> /dev/null
			sed -i -e "s/^.*autologin-user=.*/autologin-user=${username}/" /etc/lightdm/lightdm.conf
			sed -i -e "s/^.*autologin-user-timeout=.*/autologin-user-timeout=0/" /etc/lightdm/lightdm.conf
			sed -i -e "s/^.*pam-autologin-service=.*/pam-autologin-service=lightdm-autologin/" /etc/lightdm/lightdm.conf
		fi
	elif [[ -f /usr/bin/gdm ]];then
		configure_accountsservice "gdm"
		if ${autologin};then
			sed -i -e "s/\[daemon\]/\[daemon\]\nAutomaticLogin=${username}\nAutomaticLoginEnable=True/" /etc/gdm/custom.conf
		fi
	elif [[ -f /usr/bin/mdm ]];then
		if $(is_valid_de); then
			sed -i "s|default.desktop|$default_desktop_file.desktop|g" /etc/mdm/custom.conf
		fi
	elif [[ -f /usr/bin/sddm ]];then
		if [[ -e /etc/sddm.conf.d/kde_settings.conf ]];then
			conf_file=/etc/sddm.conf.d/kde_settings.conf
		else
			conf_file=/etc/sddm.conf
		fi
		if $(is_valid_de); then
			sed -i -e "s|^Session=.*|Session=$default_desktop_file.desktop|" $conf_file
		fi
		if ${autologin};then
			sed -i -e "s|^User=.*|User=${username}|" $conf_file
		fi
	elif [[ -f /usr/bin/lxdm ]];then
		if $(is_valid_de); then
			sed -i -e "s|^.*session=.*|session=/usr/bin/$default_desktop_executable|" /etc/lxdm/lxdm.conf
		fi
		if ${autologin};then
			sed -i -e "s/^.*autologin=.*/autologin=${username}/" /etc/lxdm/lxdm.conf
		fi
	fi
	[[ -d /run/openrc ]] && set_pam
}

gen_pw(){
	echo $(openssl passwd -6 ${password})
}

configure_user(){
	# set up user and password
	if [[ -n ${password} ]];then
		useradd -m -G ${addgroups} -p $(gen_pw) -s ${login_shell} ${username}
	else
		useradd -m -G ${addgroups} -s ${login_shell} ${username}
	fi
}

find_legacy_keymap(){
	local file="${DATADIR}/kbd-model.map"
	while read -r line || [[ -n $line ]]; do
		if [[ -z $line ]] || [[ $line == \#* ]]; then
			continue
		fi

		mapping=( $line ); # parses columns
		if [[ ${#mapping[@]} != 5 ]]; then
			continue
		fi

		if  [[ "${keytable}" != "${mapping[0]}" ]]; then
			continue
		fi

		if [[ "${mapping[3]}" = "-" ]]; then
			mapping[3]=""
		fi

		X11_LAYOUT=${mapping[1]}
		X11_MODEL=${mapping[2]}
		X11_VARIANT=${mapping[3]}
		X11_OPTIONS=${mapping[4]}
	done < $file
}

write_x11_config(){
	# write X11 keyboard configuration using previously determined
	# X11_LAYOUT, X11_MODEL, X11_VARIANT, X11_OPTIONS (from find_legacy_keymap)
	# fall back to keytable if layout is empty
	[[ -z "$X11_LAYOUT" ]] && X11_LAYOUT="${keytable}"
	[[ -z "$X11_MODEL" ]] && X11_MODEL="pc105"
	[[ -z "$X11_VARIANT" ]] && X11_VARIANT=""
	[[ -z "$X11_OPTIONS" ]] && X11_OPTIONS="terminate:ctrl_alt_bksp"

	mkdir -p "/etc/X11/xorg.conf.d"
	local XORGKBLAYOUT="/etc/X11/xorg.conf.d/00-keyboard.conf"

	echo "" >> "$XORGKBLAYOUT"
	echo "Section \"InputClass\"" > "$XORGKBLAYOUT"
	echo " Identifier \"system-keyboard\"" >> "$XORGKBLAYOUT"
	echo " MatchIsKeyboard \"on\"" >> "$XORGKBLAYOUT"
	echo " Option \"XkbLayout\" \"$X11_LAYOUT\"" >> "$XORGKBLAYOUT"
	echo " Option \"XkbModel\" \"$X11_MODEL\"" >> "$XORGKBLAYOUT"
	echo " Option \"XkbVariant\" \"$X11_VARIANT\"" >> "$XORGKBLAYOUT"
	echo " Option \"XkbOptions\" \"$X11_OPTIONS\"" >> "$XORGKBLAYOUT"
	echo "EndSection" >> "$XORGKBLAYOUT"
}

configure_language(){
    # hack to be able to set the locale on bootup
    local lang=$(get_lang)
    keytable=$(get_keytable)
    local timezone=$(get_tz)
    # Fallback
    [[ -z "${lang}" ]] && lang="en_US"
    [[ -z "${keytable}" ]] && keytable="us"
    [[ -z "${timezone}" ]] && timezone="Etc/UTC"

    sed -e "s/#${lang}.UTF-8/${lang}.UTF-8/" -i /etc/locale.gen

    echo "LANG=${lang}.UTF-8" >> /etc/environment

    if [[ -d /run/openrc ]]; then
        sed -i "s/keymap=.*/keymap=\"${keytable}\"/" /etc/conf.d/keymaps
    fi
    echo "KEYMAP=${keytable}" > /etc/vconsole.conf
    echo "LANG=${lang}.UTF-8" > /etc/locale.conf
    ln -sf /usr/share/zoneinfo/${timezone} /etc/localtime

    # Determine X11 layout from keytable
    find_legacy_keymap

    write_x11_config

    # Also set the keymap via localectl so that GNOME/KDE Wayland sessions pick it up
    if command -v localectl >/dev/null 2>&1 && [[ -n "${X11_LAYOUT}" ]]; then
        localectl set-x11-keymap "${X11_LAYOUT}" "${X11_MODEL}" "${X11_VARIANT}" "${X11_OPTIONS}"
    fi

    loadkeys "${keytable}"

    locale-gen
    echo "Configured language: ${lang}" >> /var/log/manjaro-live.log
    echo "Configured keymap: ${keytable}" >> /var/log/manjaro-live.log
    echo "Configured timezone: ${timezone}" >> /var/log/manjaro-live.log
}

configure_machine_id(){
	if [ -e "/etc/machine-id" ] ; then
		# delete existing machine-id
		echo "Deleting existing machine-id ..." >> /var/log/manjaro-live.log
		rm /etc/machine-id
	fi
	# set unique machine-id
	echo "Setting machine-id ..." >> /var/log/manjaro-live.log
	dbus-uuidgen --ensure=/etc/machine-id
	ln -sf /etc/machine-id /var/lib/dbus/machine-id
}

configure_sudoers_d(){
	echo "%wheel  ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/g_wheel
	echo "root ALL=(ALL) ALL"  > /etc/sudoers.d/u_root
	#echo "${username} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/u_live
}

configure_swap(){
	local swapdev="$(fdisk -l 2>/dev/null | grep swap | cut -d' ' -f1)"
	if [ -e "${swapdev}" ]; then
		swapon ${swapdev}
	fi
}

configure_user_root(){
	# set up root password
	echo "root:${password}" | chroot $1 chpasswd
	cp /etc/skel/.{bash_profile,bashrc,bash_logout} /root/
	[[ -f /etc/skel/.extend.bashrc ]] && cp /etc/skel/.extend.bashrc /root/
	[[ -f /etc/skel/.gtkrc-2.0 ]] && cp /etc/skel/.gtkrc-2.0 /root/
	if [[ -d /etc/skel/.config ]]; then
		cp -an /etc/skel/.config /root/
	fi
}

fix: propagate X11 keyboard layout via localectl for GNOME/KDE sessions
Ensure the live environment runs localectl set-x11-keymap in addition to
writing the xorg.conf.d snippet, so that Wayland-based desktops (GNOME, KDE)
correctly inherit the layout chosen in the bootloader. XFCE (X11) was
unaffected because it reads the Xorg configuration directly.

2 Likes

I will have a look when I find time for it.

1 Like

A diff would be more helpful. Look about right?

diff --git a/util-live-a.sh b/util-live-b.sh
index dc01b76..1d04c16 100644
--- a/util-live-a.sh
+++ b/util-live-b.sh
@@ -228,29 +228,20 @@ find_legacy_keymap(){
 		X11_LAYOUT=${mapping[1]}
 		X11_MODEL=${mapping[2]}
 		X11_VARIANT=${mapping[3]}
-		x11_OPTIONS=${mapping[4]}
+		X11_OPTIONS=${mapping[4]}
 	done < $file
 }
 
 write_x11_config(){
-	# find a x11 layout that matches the keymap
-	# in isolinux if you select a keyboard layout and a language that doesnt match this layout,
-	# it will provide the correct keymap, but not kblayout value
-	local X11_LAYOUT=
-	local X11_MODEL="pc105"
-	local X11_VARIANT=""
-	local X11_OPTIONS="terminate:ctrl_alt_bksp"
-
-	find_legacy_keymap
-
-	# layout not found, use KBLAYOUT
-	if [[ -z "$X11_LAYOUT" ]]; then
-		X11_LAYOUT="${keytable}"
-	fi
+	# write X11 keyboard configuration using previously determined
+	# X11_LAYOUT, X11_MODEL, X11_VARIANT, X11_OPTIONS (from find_legacy_keymap)
+	# fall back to keytable if layout is empty
+	[[ -z "$X11_LAYOUT" ]] && X11_LAYOUT="${keytable}"
+	[[ -z "$X11_MODEL" ]] && X11_MODEL="pc105"
+	[[ -z "$X11_VARIANT" ]] && X11_VARIANT=""
+	[[ -z "$X11_OPTIONS" ]] && X11_OPTIONS="terminate:ctrl_alt_bksp"
 
-	# create X11 keyboard layout config
 	mkdir -p "/etc/X11/xorg.conf.d"
-
 	local XORGKBLAYOUT="/etc/X11/xorg.conf.d/00-keyboard.conf"
 
 	echo "" >> "$XORGKBLAYOUT"
@@ -285,8 +276,16 @@ configure_language(){
     echo "LANG=${lang}.UTF-8" > /etc/locale.conf
     ln -sf /usr/share/zoneinfo/${timezone} /etc/localtime
 
+    # Determine X11 layout from keytable
+    find_legacy_keymap
+
     write_x11_config
 
+    # Also set the keymap via localectl so that GNOME/KDE Wayland sessions pick it up
+    if command -v localectl >/dev/null 2>&1 && [[ -n "${X11_LAYOUT}" ]]; then
+        localectl set-x11-keymap "${X11_LAYOUT}" "${X11_MODEL}" "${X11_VARIANT}" "${X11_OPTIONS}"
+    fi
+
     loadkeys "${keytable}"
 
     locale-gen

A post was split to a new topic: Development ISO scheduled build actions failing

New ISOs with applied fix: Release 202608041243 · manjaro/release-review · GitHub

2 Likes

manjaro-kde-26.1-testing-260804-linux618.iso boots to desktop with keyboard set as chosen in the GRUB menu - thank you!

USB media with GRUB2 and EFI and autoiso.cfg GRUB loopback booting ISO files on desktop PC with AMD Ryzen 5 3600 CPU and Radeon RX 590 graphics. In the ISOs GRUB boot menu I choose tz=Europe/Copenhagen and keytable=dk and leave lang=en_US and boot with open source drivers.

manjaro-kde-26.1-testing-260804-linux618.iso boots to desktop logged in as manjaro, and keyboard is DK both in Konsole on desktop and tty.

❯ cat /var/log/manjaro-live.log
Loaded /etc/manjaro-tools/live.conf: 0.003ms
Got consolefont and arch x86_64: 0.092ms
Configured language: en_US
Configured keymap: dk
Configured timezone: Europe/Copenhagen
Finished localization: 2.367ms
Configured samba: 0.096ms

❯ localectl
System Locale: LANG=en_US.UTF-8
    VC Keymap: dk-latin1
   X11 Layout: dk
    X11 Model: pc105
  X11 Options: terminate:ctrl_alt_bksp

❯ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-x86_64 lang=en_US keytable=dk tz=Europe/Copenhagen img_dev=/dev/disk/by-uuid/ img_loop=/ISOboot/manjaro-kde-26.1-testing-260804-linux618.iso misobasedir=manjaro misolabel=MANJARO_KDE_261 quiet systemd.show_status=1 splash driver=free nouveau.modeset=1 i915.modeset=1 radeon.modeset=1
/var/log/mhwd-live.log
Running MHWD...
e[1me[31mWarning: e[mconfig '/var/lib/mhwd/db/pci/network_drivers/r8168/MHWDCONFIG' is invalid!
e[1me[31mWarning: e[mconfig '/var/lib/mhwd/db/pci/network_drivers/rt3562sta/MHWDCONFIG' is invalid!
e[1me[31m> e[mUsing config 'video-linux' for device: 0000:08:00.0 (0300:1002:67df) Display controller ATI Technologies Inc Ellesmere [Radeon RX 470/480/570/570X/580/580X/590]
e[1me[31m> e[mInstalling video-linux...
e[0;32mwarning: database file for 'core' does not exist (use '-Sy' to download)
e[me[0;32mwarning: database file for 'extra' does not exist (use '-Sy' to download)
e[me[0;32mwarning: database file for 'multilib' does not exist (use '-Sy' to download)
e[me[0;32mSourcing /etc/mhwd-x86_64.conf
e[me[0;32mHas lib32 support: true
e[me[0;32mSourcing /var/lib/mhwd/db/pci/graphic_drivers/video-linux/MHWDCONFIG
e[me[0;32mProcessing classid: 0300
e[me[0;32mSourcing /var/lib/mhwd/scripts/include/0300
e[me[0;32mProcessing classid: 0380
e[me[0;32mProcessing classid: 0302
e[me[0;32m:: Synchronizing package databases...
e[me[0;32m mhwd downloading...
e[me[0;32mresolving dependencies...
e[me[0;32mlooking for conflicting packages...
e[me[0;32m
e[me[0;32mPackages (16) lib32-libdisplay-info-0.3.0-1  lib32-vulkan-icd-loader-1.4.357.0-1  lib32-vulkan-mesa-implicit-layers-1:26.1.6-1  lib32-xcb-util-keysyms-0.4.1-2  libxvmc-1.0.15-1  vulkan-mesa-implicit-layers-1:26.1.6-1  lib32-vulkan-intel-1:26.1.6-1  lib32-vulkan-nouveau-1:26.1.6-1  lib32-vulkan-radeon-1:26.1.6-1  vulkan-intel-1:26.1.6-1  vulkan-nouveau-1:26.1.6-1  vulkan-radeon-1:26.1.6-1  xf86-video-amdgpu-25.0.0-1  xf86-video-ati-1:22.0.0-3  xf86-video-intel-1:2.99.917+939+g4a64400e-1  xf86-video-nouveau-e[me[0;32m1.0.18-1
e[me[0;32m
e[me[0;32mTotal Download Size:    22.87 MiB
e[me[0;32mTotal Installed Size:  153.81 MiB
e[me[0;32m
e[me[0;32m:: Proceed with installation? [Y/n]
e[me[0;32m:: Retrieving packages...
e[me[0;32m vulkan-intel-1:26.1.6-1-x86_64 downloading...
e[me[0;32m lib32-vulkan-intel-1:26.1.6-1-x86_64 downloading...
e[me[0;32m vulkan-radeon-1:26.1.6-1-x86_64 downloading...
e[me[0;32m lib32-vulkan-radeon-1:26.1.6-1-x86_64 downloading...
e[me[0;32m lib32-vulkan-nouveau-1:26.1.6-1-x86_64 downloading...
e[me[0;32m vulkan-nouveau-1:26.1.6-1-x86_64 downloading...
e[me[0;32m xf86-video-intel-1:2.99.917+939+g4a64400e-1-x86_64 downloading...
e[me[0;32m lib32-vulkan-icd-loader-1.4.357.0-1-x86_64 downloading...
e[me[0;32m xf86-video-ati-1:22.0.0-3-x86_64 downloading...
e[me[0;32m xf86-video-nouveau-1.0.18-1-x86_64 downloading...
e[me[0;32m lib32-libdisplay-info-0.3.0-1-x86_64 downloading...
e[me[0;32m xf86-video-amdgpu-25.0.0-1-x86_64 downloading...
e[me[0;32m vulkan-mesa-implicit-layers-1:26.1.6-1-x86_64 downloading...
e[me[0;32m lib32-vulkan-mesa-implicit-layers-1:26.1.6-1-x86_64 downloading...
e[me[0;32m libxvmc-1.0.15-1-x86_64 downloading...
e[me[0;32m lib32-xcb-util-keysyms-0.4.1-2-x86_64 downloading...
e[me[0;32mchecking keyring...
e[me[0;32mchecking package integrity...
e[me[0;32mloading package files...
e[me[0;32mchecking for file conflicts...
e[me[0;32mchecking available disk space...
e[me[0;32m:: Processing package changes...
e[me[0;32minstalling xf86-video-ati...
e[me[0;32minstalling xf86-video-amdgpu...
e[me[0;32minstalling libxvmc...
e[me[0;32minstalling xf86-video-intel...
e[me[0;32m>>> This driver now uses DRI3 as the default Direct Rendering
e[me[0;32m    Infrastructure. You can try falling back to DRI2 if you run
e[me[0;32m    into trouble. To do so, save a file with the following
e[me[0;32m    content as /etc/X11/xorg.conf.d/20-intel.conf :
e[me[0;32m      Section "Device"
e[me[0;32m        Identifier  "Intel Graphics"
e[me[0;32m        Driver      "intel"
e[me[0;32m        Option      "DRI" "2"             # DRI3 is now default
e[me[0;32m        #Option      "AccelMethod"  "sna" # default
e[me[0;32m        #Option      "AccelMethod"  "uxa" # fallback
e[me[0;32m      EndSection
e[me[0;32mOptional dependencies for xf86-video-intel
e[me[0;32m    libxrandr: for intel-virtual-output [installed]
e[me[0;32m    libxinerama: for intel-virtual-output [installed]
e[me[0;32m    libxcursor: for intel-virtual-output [installed]
e[me[0;32m    libxtst: for intel-virtual-output [installed]
e[me[0;32m    libxss: for intel-virtual-output [installed]
e[me[0;32minstalling xf86-video-nouveau...
e[me[0;32minstalling vulkan-mesa-implicit-layers...
e[me[0;32minstalling vulkan-intel...
e[me[0;32mOptional dependencies for vulkan-intel
e[me[0;32m    vulkan-mesa-layers: additional vulkan layers
e[me[0;32minstalling vulkan-nouveau...
e[me[0;32mOptional dependencies for vulkan-nouveau
e[me[0;32m    vulkan-mesa-layers: additional vulkan layers
e[me[0;32minstalling vulkan-radeon...
e[me[0;32mOptional dependencies for vulkan-radeon
e[me[0;32m    vulkan-mesa-layers: additional vulkan layers
e[me[0;32minstalling lib32-libdisplay-info...
e[me[0;32minstalling lib32-vulkan-icd-loader...
e[me[0;32mOptional dependencies for lib32-vulkan-icd-loader
e[me[0;32m    lib32-vulkan-driver: packaged vulkan driver [pending]
e[me[0;32minstalling lib32-vulkan-mesa-implicit-layers...
e[me[0;32minstalling lib32-xcb-util-keysyms...
e[me[0;32minstalling lib32-vulkan-intel...
e[me[0;32mOptional dependencies for lib32-vulkan-intel
e[me[0;32m    lib32-vulkan-mesa-layers: additional vulkan layers
e[me[0;32minstalling lib32-vulkan-nouveau...
e[me[0;32mOptional dependencies for lib32-vulkan-nouveau
e[me[0;32m    lib32-vulkan-mesa-layers: additional vulkan layers
e[me[0;32minstalling lib32-vulkan-radeon...
e[me[0;32mOptional dependencies for lib32-vulkan-radeon
e[me[0;32m    lib32-vulkan-mesa-layers: additional vulkan layers
e[me[0;32m:: Running post-transaction hooks...
e[me[0;32m(1/1) Arming ConditionNeedsUpdate...
e[me[0;32mxf86-video-ati: install reason has been set to 'explicitly installed'
e[me[0;32mxf86-video-amdgpu: install reason has been set to 'explicitly installed'
e[me[0;32mxf86-video-intel: install reason has been set to 'explicitly installed'
e[me[0;32mxf86-video-nouveau: install reason has been set to 'explicitly installed'
e[me[0;32mvulkan-intel: install reason has been set to 'explicitly installed'
e[me[0;32mvulkan-nouveau: install reason has been set to 'explicitly installed'
e[me[0;32mvulkan-radeon: install reason has been set to 'explicitly installed'
e[me[0;32mlib32-vulkan-intel: install reason has been set to 'explicitly installed'
e[me[0;32mlib32-vulkan-nouveau: install reason has been set to 'explicitly installed'
e[me[0;32mlib32-vulkan-radeon: install reason has been set to 'explicitly installed'
e[me[1me[31m> e[mSuccessfully installed video-linux
MHWD DONE

4 Likes