Wednesday, June 23, 2021

Assigning a HUION tablet to a single screen in a multi-screen Linux environment

Couldn't get the GNOME WACOM applet to actually pin my HUION tablet to a single screen so I did a little research, found out what commands to use and wrote a script to simplify it.  Has to be run at each boot.  I kept this as generic as possible but because of differences in the way that HUION constructs their device name strings it will probably have to be slightly modified to work.

This looks at active displays and connected tablets and gives you a simple menu to select from.  Defaults to whatever display you have designated as "primary".

#!/bin/bash


# Get list of active displays
DIS_LIST=($(xrandr | grep 'connected' | grep -v 'disconnected' | awk '{print $1}'))
unset DIS_PRI

#=======[SELECT DISPLAY]================


# Unset validation check 
unset gDISv

# Loop until validation check is passed
until [[ $gDISv == "yes" ]]; do

   echo ""
   echo "The following ${#DIS_LIST[@]} displays were detected"
   printf "%2s | %10s | %10s | %7s\n" "#" "Resolution" "Physical Size" "Priority"
   echo "-----------------------------------"
   for (( i=0; i<${#DIS_LIST[@]}; i++ )); do
      # Offset index to offer nicer options - this way the display numbering will
      #  not start at zero, AND theoretically it will match the XORG display
      #  numbering shown in GNOME
      let j=$i+1
   
      # read the xrandr line into a variable
      DLINE=$(xrandr | grep "${DIS_LIST[$i]} c")
   
      # Pull screen resolution and physical size to make it easier to identify which display is which
      THIS_RES=$(echo $DLINE | sed 's/primary//' | awk '{print $3}' | awk -F'+' '{print $1}')
      THIS_SIZ=$(echo $DLINE | sed 's/primary//' | awk '{print $(NF-2), $(NF-1), $NF}')
   
      # Mark which display is primary (using the offset index) so we can default
      #  to this choice
      if [[ -n $(echo $DLINE | grep -o 'primary') ]]; then
         DIS_PRI=$j
      fi
      
      printf "%2s | %10s | %10s | %7s\n" "$j" "$THIS_RES" "$THIS_SIZ" "$(echo $DLINE | grep -o 'primary')"
   done

   echo ""
   read -p "Select a display (1-${#DIS_LIST[@]})? [$DIS_PRI]:" gDIS
   # If no input was provided, set value to default
   if [[ -z $gDIS ]]; then let gDIS=$DIS_PRI; fi
   # Validate input
   if [[ $gDIS -gt 0 ]] && [[ $gDIS -lt ${#DIS_LIST[@]} ]]; then
      gDISv="yes"
      DIS_TGT=${DIS_LIST[${gDIS}-1]}
   else
      echo "[$gDIS] is not a valid selection."
      unset gDIS
      echo ""
      gDISv="no"
   fi
done


#=========[Find XINPUT IDs]============

ID_STYLUS=$(xinput | grep pointer | grep HUION | grep -i pen | awk '{print $(NF-3)}'| awk -F'=' '{print $2}')

#echo "XINPUT device ids: Stylus ($ID_STYLUS), Pad ($ID_PAD)"

#=========[Assign Tablet To Screen]=========
echo "Assigning the HUION stylus to display $gDIS: $DIS_TGT"
xinput map-to-output ${ID_STYLUS} ${DIS_TGT}