1

I've been trying to run a command, when I press the top key on my Bamboo Ink Pen. I realized that it connects via Bluetooth, when I press the button and ceases the connection, when I release it.

I stumbled over Run a script when bluetooth device is connected and when I run

udevadm monitor --environment --udev --kernel --property

and press the button once, I get the following output:

KERNEL[5118.647193] add      /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585 (bluetooth)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585
SUBSYSTEM=bluetooth
DEVTYPE=link
SEQNUM=4094

UDEV  [5118.657098] add      /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585 (bluetooth)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585
SUBSYSTEM=bluetooth
DEVTYPE=link
SEQNUM=4094
USEC_INITIALIZED=5118654305
SYSTEMD_ALIAS=/sys/subsystem/bluetooth/devices/hci0:3585
SYSTEMD_WANTS=bluetooth.target
SYSTEMD_USER_WANTS=bluetooth.target
TAGS=:systemd:

KERNEL[5119.311809] remove   /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585 (bluetooth)
ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585
SUBSYSTEM=bluetooth
DEVTYPE=link
SEQNUM=4095

UDEV  [5119.317304] remove   /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585 (bluetooth)
ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585
SUBSYSTEM=bluetooth
DEVTYPE=link
SEQNUM=4095
USEC_INITIALIZED=5118654305
SYSTEMD_ALIAS=/sys/subsystem/bluetooth/devices/hci0:3585
SYSTEMD_WANTS=bluetooth.target
SYSTEMD_USER_WANTS=bluetooth.target
TAGS=:systemd:

Unfortunately there is no idVendor or idProduct.

When I run

sudo tail -f /var/log/syslog

though, it complains that the file does not exist.

My udev rules looks like this so far.

# Run a program when my Bamboo Ink is connected
ACTION=="add" , SUBSYSTEM=="bluetooth", ATTR{idVendor}=="xxx", ATTR{idProduct}=="yyy", ATTRS{model}=="Bamboo Ink", RUN+="xournalpp"

Guessing the model is "Bamboo Ink", since I found this line in journalctl -b

Feb 26 14:57:35 X380-Yoga kernel: wacom 0005:056A:035F.000C: Unknown device_type for 'Bamboo Ink'. Ignoring.

So I need to find the idVendor, idProduct and model. Is there another way to do that?

neolith
  • 213
  • 2
  • 7

2 Answers2

2

Here is how I do it:

ACTION=="add" , SUBSYSTEM=="bluetooth", DEVPATH=="/devices/pci0000:00/0000:00:14.0/usb1/1-10/1-10:1.0/bluetooth/hci0/hci0:3585", RUN+="/home/gvb/bin/run-pen-state.sh"

What I wanted to do was switch between pen and eraser and in Xournal. The two scripts needed for this are shown below. They need two small utilities: wmctrl and xdotool...

Contents of "run-pen-state.sh" is

#!/bin/csh
sudo -u gvb -i /home/gvb/bin/pen-state

while "pen-state" itself is

#!/usr/bin/perl -w

$home=$ENV{'HOME'};
$store=`grep "#state: " ~/bin/pen-state | grep -v store`;
chomp($store);

$command=`export DISPLAY=:0; export XAUTHORITY=$home/.Xauthority; wmctrl -l`;
foreach $line (split(/\n/,$command)){
  if (($line=~ /Xournal/)&&($line=~ /$filename/)){
    $winid=(split(/ /,$line))[0];
  }
}


if($winid){
  system("export DISPLAY=:0; export XAUTHORITY=$home/.Xauthority; wmctrl -i -a $winid");


  if($store =~ /pen/){
    $now="state: eraser";
    system("export DISPLAY=:0; export XAUTHORITY=$home/.Xauthority; xdotool key shift+ctrl+e");
  }else{
    $now="state: pen";
    system("export DISPLAY=:0; export XAUTHORITY=$home/.Xauthority; xdotool key shift+ctrl+p");
  }

  $now="#$now";

  print "$store\n";
  print "$now\n";

  open(SELF,"$home/bin/pen-state");
  read(SELF,$self,-s "$home/bin/pen-state",0);
  close(SELF);
  $self=~ s/$store/$now/;
  open(SELF,">$home/bin/pen-state");
  print SELF $self;
  close(SELF);
}

#state: pen
Guillaume
  • 21
  • 2
1

Update February 2022:
I just noticed, with Ubuntu 22.04, Kernel 5.16.8 and Gnome 41.3 it works out of the box. The top button is detected as Super+AudioMicMute combo which you can use to assign any shortcut in Gnome settings. But I don't know when it started to work.

Original answer:
I have nearly the same approach as in the previous answer from Guillaume. But the problem with his answer for me is, that I found no way to distinguish which device triggered the add action of the bluetooth subsystem, so that Guillaume's simple rule also matched when I connected any other device via bluetooth. But with my Lenovo active pen 2 I noticed that one of two things can happen, whenever I press the top button.

Case 1) The pen connects and disconnects within one or two seconds. udevadm monitor shows only the add and remove action.

Case 2) After udev's add action the pen is recognized as HID named Lenovo Active Pen2 Keyboard. Then it takes about 10 seconds until it is removed.

ACTION=="add", SUBSYSTEM=="bluetooth", DEVPATH=="/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585", RUN+="/usr/local/bin/bluetooth_event_detected.sh add"
ACTION=="remove", SUBSYSTEM=="bluetooth", DEVPATH=="/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:3585", RUN+="/usr/local/bin/bluetooth_event_detected.sh remove"
ACTION=="add", SUBSYSTEM=="hid", DEVPATH=="/devices/virtual/misc/uhid/0005:17EF:60A8.*", RUN+="/usr/local/bin/bluetooth_event_detected.sh force"

So I watch for the add and remove actions in my udev rule, which triggers a script that times how long it takes between an add and the next remove event. If it takes less than 2 seconds it assumes that this was the pen and sets a flag under /tmp/stylus. The same happens in case two when the pen is recognized as HID.

#!/bin/bash
# PATH is not provided in an udev environment
PATH=/bin:/usr/bin:/usr/local/bin

DIRECTORY=/tmp/stylus
TSFILE=$DIRECTORY/bluetooth_timestamp
BTN_PRESSED_FLAG=$DIRECTORY/stylus_button_pressed
TIME_DELTA="2"  

ACTION=$1
NOW=$(date +%s)


mkdir -p $DIRECTORY 
chmod 777 $DIRECTORY

if [ "$ACTION" = "add" ]; then
        echo $NOW > $TSFILE                   
elif [ "$ACTION" = "remove" ]; then
        ADDED_TS=$(cat $TSFILE)
        DIFF=$(($NOW-$ADDED_TS))
        echo diff: $DIFF
        # if the time between adding and removing is 
        # 2 seconds or less, we assume the stylus button
        # was pressed
        if [ "$DIFF" -le "$TIME_DELTA" ]; then
                touch $BTN_PRESSED_FLAG          
                chmod 666 $BTN_PRESSED_FLAG 
        fi
elif [ "$ACTION" = "force" ]; then
        touch $BTN_PRESSED_FLAG
        chmod 666 $BTN_PRESSED_FLAG
fi    

Last I have a simple script autostarted when I log into my desktop environment, that keeps watching for that flag under /tmp/stylus and executes gnome-screenshot -i.

#!/bin/bash

FILE=/tmp/stylus/stylus_button_pressed
CMD="gnome-screenshot -i"

while true; do
        if [ -f $FILE ]; then
                echo running command
                $CMD
                rm $FILE
        fi
        sleep 0.1
done

Not elegant, but working.

flurl
  • 21
  • 1
  • 4