← paintstorm-distrobox-legacy

Add diagnostics and fixes for mouse pointer freezing issue with OTD

35091136cb051c31234b9399f7de4c78cca1db65 · Claude · Jan 24, 2026 09:17

New issue discovered: When using OpenTabletDriver, the mouse freezes while
drawing with the pen and only unfreezes with Alt+Tab. This is an X11 pointer
grabbing conflict.

New files:
- diagnose-pointer-freeze.sh: Comprehensive diagnostic for pointer conflicts
  * Shows device roles and master pointer attachments
  * Tests pointer grab behavior
  * Identifies conflicting devices
  * Provides specific fix commands

- fix-pointer-freeze.sh: Interactive menu to fix common pointer issues
  * Option 1: Disable all native Huion devices (recommended)
  * Option 2: Restart X11 input subsystem
  * Option 3: Reset OTD daemon
  * Option 4: Switch to native HID mode
  * Option 5: Show current device status

Documentation updates:
- TABLET-INPUT-GUIDE.md: Added comprehensive section on mouse freezing
  * Explained X11 pointer grabbing behavior
  * Provided 4 different fix approaches
  * Added permanent solution options
  * Documented when to use OTD vs native HID
  * Explained technical details of the issue

The mouse freeze occurs because:
- X11 core pointer protocol allows only one active pointer device
- When pen is in use, it can grab exclusive pointer control
- This suppresses mouse events until focus changes
- Alt+Tab releases the grab by changing window focus

Recommended solution: Use native HID unless OTD features are required.

+466 · 3 files changed

  • TABLET-INPUT-GUIDE.md +139 −0
  • diagnose-pointer-freeze.sh +164 −0
  • fix-pointer-freeze.sh +163 −0
diff --git a/TABLET-INPUT-GUIDE.md b/TABLET-INPUT-GUIDE.md
index fa095a2..fdae8a1 100644
--- a/TABLET-INPUT-GUIDE.md
+++ b/TABLET-INPUT-GUIDE.md
@@ -270,3 +270,142 @@ You're using the **generic Linux HID driver** (not hid_uclogic), which is why pr
 - **Advanced**: Use OTD + disable native devices via xinput
 
 Choose based on whether you need OTD's features (custom curves, remapping, area config).
+
+## Known Issue: Mouse Freezing with OTD
+
+### Symptoms
+- Pen/tablet works correctly
+- Mouse freezes when you draw with the pen
+- Mouse unfreezes when you Alt+Tab or change window focus
+- This repeats every time you use the pen
+
+### Cause
+This is an X11 **pointer grabbing conflict**. When you use the pen:
+1. The tablet device grabs pointer focus
+2. X11 suppresses mouse events (thinking pen = exclusive input)
+3. Window focus change releases the grab
+4. This happens because X11 doesn't expect both devices active simultaneously
+
+### Quick Fixes
+
+#### Fix 1: Use the automated fix script
+```bash
+./fix-pointer-freeze.sh
+# Choose option 1: Disable all native Huion devices
+```
+
+#### Fix 2: Manual disable
+```bash
+# Disable native devices
+xinput disable 11  # Native stylus
+xinput disable 24  # Native eraser
+
+# Verify they're floating (disabled)
+xinput list | grep floating
+```
+
+#### Fix 3: Restart OTD daemon
+```bash
+pkill otd-daemon
+otd-daemon &
+sleep 2
+xinput disable 11
+xinput disable 24
+```
+
+#### Fix 4: Switch back to native HID
+If the freeze persists, just use native HID (it works perfectly):
+```bash
+pkill otd-daemon
+xinput enable 11
+xinput enable 24
+~/paintstorm  # Pressure works!
+```
+
+### Diagnostic Tool
+
+To diagnose the pointer freeze issue:
+```bash
+./diagnose-pointer-freeze.sh
+```
+
+This will show you:
+- Which devices are attached to the master pointer
+- Whether there are device conflicts
+- Current pointer grab status
+- Recommended fixes
+
+### Why This Happens
+
+X11 has a single "master pointer" that controls the cursor. When multiple pointer devices (mouse + tablet) are active:
+- Some applications grab the pointer exclusively when the pen is in use
+- This prevents the mouse from generating events
+- Releasing focus (Alt+Tab) releases the grab
+- This is a limitation of X11's input architecture
+
+### Permanent Solution
+
+If you need OTD and want to avoid this issue permanently:
+
+**Option A: Create a wrapper that ensures native devices stay disabled**
+```bash
+cat > ~/paintstorm-otd-fixed << 'EOF'
+#!/bin/bash
+# Ensure OTD is running
+if ! pgrep -f otd-daemon > /dev/null; then
+    otd-daemon &
+    sleep 2
+fi
+
+# Always disable native devices before launching
+xinput disable 11 2>/dev/null || true
+xinput disable 24 2>/dev/null || true
+
+# Launch Paintstorm
+~/paintstorm
+EOF
+
+chmod +x ~/paintstorm-otd-fixed
+```
+
+**Option B: Use native HID (recommended if you don't need OTD features)**
+```bash
+# Stop OTD permanently
+pkill otd-daemon
+
+# Don't start it on boot
+# Remove from startup applications if configured
+
+# Use Paintstorm with native HID
+~/paintstorm  # Works perfectly
+```
+
+### Technical Details
+
+The freeze happens because:
+1. X11 uses a "core pointer protocol" where one device controls the cursor
+2. When you have multiple pointer devices (mouse + tablet), X11 must decide which is active
+3. Applications can request "pointer grabs" for exclusive input
+4. Paintstorm (or X11) is grabbing the pointer when the pen is active
+5. This suppresses mouse events until the grab is released
+6. Alt+Tab changes window focus, which releases pointer grabs
+
+Modern Wayland compositors handle this better, but Paintstorm requires X11.
+
+## Choosing Your Configuration
+
+### Use Native HID If:
+- ✅ Pressure and tilt already work
+- ✅ You don't need custom pressure curves
+- ✅ You don't need pen button remapping
+- ✅ You want simple, trouble-free setup
+- ✅ You experience mouse freezing with OTD
+
+### Use OTD If:
+- ✅ You need custom pressure curves
+- ✅ You need pen button remapping
+- ✅ You need precise tablet area configuration
+- ✅ You're willing to disable native devices and troubleshoot pointer issues
+- ✅ You need features not available in native HID
+
+**Most users should use native HID** - it works out of the box with full pressure and tilt support.
diff --git a/diagnose-pointer-freeze.sh b/diagnose-pointer-freeze.sh
new file mode 100755
index 0000000..4ce1b23
--- /dev/null
+++ b/diagnose-pointer-freeze.sh
@@ -0,0 +1,164 @@
+#!/bin/bash
+# Diagnose and fix pointer device conflicts with OTD
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+BOLD='\033[1m'
+NC='\033[0m'
+
+echo "=========================================="
+echo "Pointer Device Conflict Diagnostic"
+echo "=========================================="
+echo ""
+
+echo "Current pointer devices:"
+echo ""
+xinput list | grep -E "(pointer|Virtual|HUION)" | nl
+
+echo ""
+echo "=========================================="
+echo "Device Roles"
+echo "=========================================="
+echo ""
+
+# Get master pointer info
+MASTER_POINTER=$(xinput list | grep "Virtual core pointer" | grep -o 'id=[0-9]*' | cut -d= -f2)
+echo "Master pointer device: id=$MASTER_POINTER"
+echo ""
+
+# Check what's attached to master pointer
+echo "Devices attached to master pointer:"
+xinput list | grep -A 20 "Virtual core pointer" | grep "↳" | grep -E "(pointer|stylus|eraser|mouse)" | sed 's/^/  /'
+
+echo ""
+echo "=========================================="
+echo "Checking for Conflicts"
+echo "=========================================="
+echo ""
+
+# Look for multiple active tablet devices
+NATIVE_COUNT=$(xinput list | grep -i "HUION" | grep -v "floating" | grep -v "OpenTabletDriver" | grep -E "(stylus|eraser)" | wc -l)
+VIRTUAL_COUNT=$(xinput list | grep -i "OpenTabletDriver" | grep -E "(stylus|eraser)" | wc -l)
+
+echo "Native Huion devices (active): $NATIVE_COUNT"
+echo "OTD virtual devices: $VIRTUAL_COUNT"
+echo ""
+
+if [ "$NATIVE_COUNT" -gt 0 ]; then
+    echo -e "${YELLOW}⚠ Native Huion devices are still attached to master pointer${NC}"
+    echo "  This can cause pointer grabbing issues"
+    echo ""
+    echo "Devices that should be disabled:"
+    xinput list | grep -i "HUION" | grep -v "floating" | grep -v "OpenTabletDriver" | sed 's/^/  /'
+    echo ""
+fi
+
+# Check for mouse devices
+MOUSE_COUNT=$(xinput list | grep -iE "(mouse|logitech|mx anywhere)" | grep "pointer" | wc -l)
+echo "Mouse devices detected: $MOUSE_COUNT"
+
+echo ""
+echo "=========================================="
+echo "Testing Pointer Grab Behavior"
+echo "=========================================="
+echo ""
+
+echo "This test will show if pointer events are being grabbed."
+echo "Move your mouse for 3 seconds..."
+echo ""
+
+MOUSE_ID=$(xinput list | grep -i "mouse" | grep "pointer" | head -1 | grep -o 'id=[0-9]*' | cut -d= -f2)
+if [ -n "$MOUSE_ID" ]; then
+    MOUSE_EVENTS=$(timeout 3 xinput test "$MOUSE_ID" 2>&1 | grep -c "motion" || true)
+    echo "Mouse events received: $MOUSE_EVENTS"
+
+    if [ "$MOUSE_EVENTS" -gt 0 ]; then
+        echo -e "${GREEN}✓ Mouse is working${NC}"
+    else
+        echo -e "${RED}✗ Mouse is not responding${NC}"
+    fi
+else
+    echo -e "${YELLOW}No mouse device found for testing${NC}"
+fi
+
+echo ""
+echo "=========================================="
+echo "DIAGNOSIS"
+echo "=========================================="
+echo ""
+
+if [ "$NATIVE_COUNT" -gt 0 ]; then
+    echo -e "${YELLOW}Issue: Native tablet devices still active${NC}"
+    echo ""
+    echo "When native devices are attached to the master pointer alongside"
+    echo "OTD virtual devices, X11 can get confused about pointer focus."
+    echo ""
+    echo "Solution: Disable native devices"
+    echo ""
+    xinput list | grep -i "HUION" | grep -v "floating" | grep -v "OpenTabletDriver" | while read line; do
+        ID=$(echo "$line" | grep -o 'id=[0-9]*' | cut -d= -f2)
+        NAME=$(echo "$line" | sed 's/.*↳ //' | sed 's/id=.*//' | xargs)
+        echo "  xinput disable $ID  # $NAME"
+    done
+    echo ""
+fi
+
+echo ""
+echo "=========================================="
+echo "Common Fixes for Pointer Freezing"
+echo "=========================================="
+echo ""
+
+echo "1. Ensure native devices are disabled (floating)"
+echo "   xinput list | grep floating"
+echo ""
+
+echo "2. Set OTD virtual device as the only active tablet"
+echo "   (Native devices should show [floating slave])"
+echo ""
+
+echo "3. Check if Paintstorm has tablet input settings"
+echo "   - Look for input device preferences"
+echo "   - Disable 'tablet mode' if it exists"
+echo "   - Try 'relative' instead of 'absolute' mode"
+echo ""
+
+echo "4. Restart X11 session (logout/login)"
+echo "   Sometimes X11 pointer state gets stuck"
+echo ""
+
+echo "5. Try disabling pen pressure in Paintstorm"
+echo "   Then re-enable it to reset the input handling"
+echo ""
+
+OTD_VID=$(xinput list | grep "OpenTabletDriver.*stylus" | grep -o 'id=[0-9]*' | cut -d= -f2 | head -1)
+if [ -n "$OTD_VID" ]; then
+    echo "6. Check OTD virtual device properties"
+    echo "   xinput list-props $OTD_VID | grep -i mode"
+    echo ""
+fi
+
+echo "=========================================="
+echo "Alternative: Use Native HID Instead"
+echo "=========================================="
+echo ""
+
+echo "If the pointer freeze persists with OTD, consider:"
+echo ""
+echo "1. Stop OTD completely:"
+echo "   pkill otd-daemon"
+echo ""
+echo "2. Re-enable native devices:"
+echo "   xinput enable 11"
+echo "   xinput enable 24"
+echo ""
+echo "3. Use Paintstorm with native HID support"
+echo "   (You mentioned pressure works without OTD)"
+echo ""
+echo "You only need OTD if you require:"
+echo "  - Custom pressure curves"
+echo "  - Pen button remapping"
+echo "  - Advanced area configuration"
+echo ""
diff --git a/fix-pointer-freeze.sh b/fix-pointer-freeze.sh
new file mode 100755
index 0000000..c01621e
--- /dev/null
+++ b/fix-pointer-freeze.sh
@@ -0,0 +1,163 @@
+#!/bin/bash
+# Quick fixes for mouse freezing when using tablet with OTD
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+BOLD='\033[1m'
+NC='\033[0m'
+
+echo "=========================================="
+echo "Pointer Freeze Fix"
+echo "=========================================="
+echo ""
+
+echo "Choose a fix:"
+echo ""
+echo "1) Disable all native Huion devices (recommended first step)"
+echo "2) Restart X11 input subsystem (kills and restarts X11)"
+echo "3) Reset OTD (stop and restart otd-daemon)"
+echo "4) Switch to native HID (stop OTD, re-enable native devices)"
+echo "5) Show current device status"
+echo "6) Exit"
+echo ""
+read -p "Choice [1-6]: " choice
+
+case $choice in
+    1)
+        echo ""
+        echo "Disabling all native Huion devices..."
+
+        # Find and disable all Huion devices except OTD virtual ones
+        xinput list | grep -i "HUION" | grep -v "OpenTabletDriver" | while read line; do
+            ID=$(echo "$line" | grep -o 'id=[0-9]*' | cut -d= -f2)
+            NAME=$(echo "$line" | sed 's/.*↳ //' | sed 's/id=.*//' | xargs)
+
+            if [ -n "$ID" ]; then
+                xinput disable "$ID" 2>/dev/null
+                if [ $? -eq 0 ]; then
+                    echo -e "${GREEN}✓ Disabled: $NAME (id=$ID)${NC}"
+                else
+                    echo -e "${YELLOW}⚠ Already disabled or couldn't disable: $NAME${NC}"
+                fi
+            fi
+        done
+
+        echo ""
+        echo "Current status:"
+        xinput list | grep -i "HUION" | sed 's/^/  /'
+        echo ""
+        echo -e "${GREEN}Done!${NC} Try using Paintstorm now."
+        echo "If the mouse still freezes, try option 2 or 3."
+        ;;
+
+    2)
+        echo ""
+        echo -e "${YELLOW}Warning: This will restart your X11 session!${NC}"
+        echo "All applications will close. Make sure to save your work."
+        echo ""
+        read -p "Continue? [y/N]: " confirm
+
+        if [[ "$confirm" =~ ^[Yy]$ ]]; then
+            echo "Restarting X11..."
+            sudo systemctl restart display-manager
+        else
+            echo "Cancelled."
+        fi
+        ;;
+
+    3)
+        echo ""
+        echo "Restarting OpenTabletDriver..."
+
+        # Stop OTD
+        pkill -9 otd-daemon 2>/dev/null
+        pkill -9 otd 2>/dev/null
+        sleep 1
+
+        # Start OTD
+        otd-daemon &
+        OTD_PID=$!
+        sleep 2
+
+        # Verify it started
+        if ps -p $OTD_PID > /dev/null 2>&1; then
+            echo -e "${GREEN}✓ OTD restarted (PID: $OTD_PID)${NC}"
+
+            # Disable native devices again
+            echo ""
+            echo "Disabling native devices..."
+            xinput disable 11 2>/dev/null
+            xinput disable 24 2>/dev/null
+
+            echo ""
+            echo "Checking for OTD virtual devices..."
+            sleep 1
+            xinput list | grep -i "OpenTabletDriver"
+
+            echo ""
+            echo -e "${GREEN}Done!${NC} Try Paintstorm again."
+        else
+            echo -e "${RED}✗ Failed to start OTD${NC}"
+            echo "Try running: otd-daemon"
+        fi
+        ;;
+
+    4)
+        echo ""
+        echo "Switching to native HID support (stopping OTD)..."
+
+        # Stop OTD
+        pkill otd-daemon 2>/dev/null
+        pkill otd 2>/dev/null
+        sleep 1
+
+        # Re-enable native devices
+        echo "Re-enabling native Huion devices..."
+        xinput enable 11 2>/dev/null && echo -e "${GREEN}✓ Enabled stylus (id=11)${NC}"
+        xinput enable 24 2>/dev/null && echo -e "${GREEN}✓ Enabled eraser (id=24)${NC}"
+
+        echo ""
+        echo "Current status:"
+        xinput list | grep -i "HUION"
+
+        echo ""
+        echo -e "${GREEN}Done!${NC} You're now using native Linux HID support."
+        echo "Pressure and tilt should work in Paintstorm."
+        echo ""
+        echo "To go back to OTD, run: otd-daemon &"
+        ;;
+
+    5)
+        echo ""
+        echo "Current device status:"
+        echo ""
+        echo "OTD daemon:"
+        if pgrep -f otd-daemon > /dev/null; then
+            echo -e "  ${GREEN}RUNNING${NC}"
+        else
+            echo -e "  ${RED}NOT RUNNING${NC}"
+        fi
+
+        echo ""
+        echo "Input devices:"
+        xinput list | grep -E "(HUION|OpenTabletDriver|Virtual core pointer)" | sed 's/^/  /'
+
+        echo ""
+        echo "Disabled devices (floating):"
+        xinput list | grep "floating" | grep -i "HUION" | sed 's/^/  /'
+        ;;
+
+    6)
+        echo "Exiting."
+        exit 0
+        ;;
+
+    *)
+        echo "Invalid choice."
+        exit 1
+        ;;
+esac
+
+echo ""