mirror of
https://github.com/stumpwm/stumpwm-contrib.git
synced 2026-09-10 07:26:25 -04:00
Add command to orient Wacom tablet to StumpWM frame
Adds a StumpWM command that detects orientation and dimensions of the current frame and runs the appropriate `xsetwacom` commands to map the Wacom tablet input to the frame.
This commit is contained in:
parent
d3101d72c3
commit
e18bbad24d
31
util/wacom/README.org
Normal file
31
util/wacom/README.org
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#+TITLE: Wacom StumpWM
|
||||
|
||||
* Requirements
|
||||
|
||||
- [[https://linux.die.net/man/1/xsetwacom][xsetwacom]]
|
||||
- [[https://linuxwacom.github.io/][Linux Wacom Project]]
|
||||
|
||||
* Installation
|
||||
|
||||
Like any other module: Add ~(load-module "wacom")~ somewhere in your ~.stumpwmrc~.
|
||||
|
||||
* Usage
|
||||
|
||||
Focus the frame you want to use your wacom tablet. Run ~map-wacom-to-current-frame~.
|
||||
|
||||
One thing that can't be detected is the physical orientation of your device. Even if we could detect landscape/portrait mode, we can't know which way is right-side-up.
|
||||
|
||||
** Parameters
|
||||
|
||||
There are a couple of parameters defined in ~wacom.lisp~ that you can edit to match the layout of your
|
||||
tablet on your desk.
|
||||
|
||||
#+begin_src lisp
|
||||
(defparameter *portrait-rotate* "ccw"
|
||||
"If you notice the directions are the reverse of what you desirte when your
|
||||
frame is in portrait orientation, then change this parameter to 'cw'.")
|
||||
|
||||
(defparameter *landscape-rotate* "half"
|
||||
"If you notice directions are the reverse of what you desire when your
|
||||
frame is in landscape orientation, then change this parameter to 'none'.")
|
||||
#+end_src
|
||||
4
util/wacom/package.lisp
Normal file
4
util/wacom/package.lisp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
;;;; package.lisp
|
||||
|
||||
(defpackage #:wacom
|
||||
(:use #:cl #:stumpwm #:cl-ppcre))
|
||||
11
util/wacom/wacom.asd
Normal file
11
util/wacom/wacom.asd
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
;;;; wacom.asd
|
||||
|
||||
(asdf:defsystem #:wacom
|
||||
:description "Map StumpWM frames to Wacom tablets using `xsetwacom`."
|
||||
:author "Eric Ihli <eihli@owoga.com>"
|
||||
:license "GPLv3"
|
||||
:version "1.0.0"
|
||||
:serial t
|
||||
:depends-on (#:stumpwm #:cl-ppcre)
|
||||
:components ((:file "package")
|
||||
(:file "wacom")))
|
||||
94
util/wacom/wacom.lisp
Normal file
94
util/wacom/wacom.lisp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
;;;; wacom.lisp
|
||||
|
||||
(in-package #:wacom)
|
||||
|
||||
(defparameter *portrait-rotate* "ccw"
|
||||
"If you notice the directions are the reverse of what you desirte when your
|
||||
frame is in portrait orientation, then change this parameter to 'cw'.")
|
||||
|
||||
(defparameter *landscape-rotate* "half"
|
||||
"If you notice directions are the reverse of what you desire when your
|
||||
frame is in landscape orientation, then change this parameter to 'none'.")
|
||||
|
||||
(defun current-frame ()
|
||||
(stumpwm::tile-group-current-frame (stumpwm:current-group)))
|
||||
|
||||
(defun tablet-id ()
|
||||
"List devices with `xsetwacom --list devices` results in something like
|
||||
the following output.
|
||||
|
||||
Wacom One by Wacom S Pen stylus id: 13 type: STYLUS
|
||||
Wacom One by Wacom S Pen eraser id: 14 type: ERASER
|
||||
|
||||
I'm not sure how type is determined. Messing around in my
|
||||
local environment I found that the type that I need to
|
||||
configure is the `STYLUS`.
|
||||
|
||||
So this function returns the ID of the STYLUS device."
|
||||
(let ((shell-output (run-shell-command "xsetwacom --list devices" t)))
|
||||
(multiple-value-bind (match groups) (cl-ppcre:scan-to-strings "id: (\\d+).*STYLUS" shell-output)
|
||||
(declare (ignore match))
|
||||
(aref groups 0))))
|
||||
|
||||
(defun reset-area! ()
|
||||
"Resets tablet area to system default."
|
||||
(run-shell-command (format nil "xsetwacom set ~A ResetArea" (tablet-id)) t))
|
||||
|
||||
(defun tablet-area ()
|
||||
"Returns (top-offset left-offset width height)."
|
||||
(mapcar
|
||||
#'parse-integer
|
||||
(cl-ppcre:split
|
||||
"\\s+"
|
||||
(run-shell-command (format nil "xsetwacom get ~A Area" (tablet-id)) t))))
|
||||
|
||||
(defun current-frame-dimensions ()
|
||||
(let* ((curframe (current-frame))
|
||||
(top (stumpwm:frame-y curframe))
|
||||
(left (stumpwm:frame-x curframe))
|
||||
(width (stumpwm:frame-width curframe))
|
||||
(height (stumpwm:frame-height curframe)))
|
||||
(list top left width height)))
|
||||
|
||||
(defun orientation ()
|
||||
"Returns either :portrait or :landscape. based on dimensions of current frame."
|
||||
(destructuring-bind (top left width height)
|
||||
(current-frame-dimensions)
|
||||
(declare (ignore top left)) ;; Only height used to get sync ratios
|
||||
(if (> height width)
|
||||
:portrait
|
||||
:landscape)))
|
||||
|
||||
(defun reset-rotate! ()
|
||||
(rotate! "none"))
|
||||
|
||||
(defun rotate! (orientation)
|
||||
(run-shell-command (format nil "xsetwacom set ~A rotate ~A" (tablet-id) orientation) t))
|
||||
|
||||
(defun -wacom-cur-frame ()
|
||||
(destructuring-bind (top left width height)
|
||||
(current-frame-dimensions)
|
||||
(let ((ratio (/ width height)))
|
||||
(reset-area!)
|
||||
(destructuring-bind
|
||||
(tablet-top tablet-left tablet-width tablet-height)
|
||||
(tablet-area)
|
||||
(declare (ignore tablet-left tablet-top)) ;; Only height used to get sync ratios
|
||||
(let* ((id (tablet-id))
|
||||
(ideal-width (* tablet-height ratio))
|
||||
(discount-ratio (min 1 (/ tablet-width ideal-width)))
|
||||
(target-width (min tablet-width ideal-width))
|
||||
(target-height (* discount-ratio tablet-height))
|
||||
(stylus-area (format nil "xsetwacom set ~A Area 0 0 ~A ~A"
|
||||
id (round target-width) target-height))
|
||||
;; Aspect ratio of 800x900 will mean we need to adjust area of Stylus also.
|
||||
(map-to-output (format nil "xsetwacom set ~A MapToOutput ~Ax~A+~A+~A" id width height left top)))
|
||||
(run-shell-command stylus-area t)
|
||||
(run-shell-command map-to-output t)
|
||||
(rotate!
|
||||
(if (eq (orientation) :portrait)
|
||||
*portrait-rotate*
|
||||
*landscape-rotate*)))))))
|
||||
|
||||
(defcommand map-wacom-to-current-frame () ()
|
||||
(-wacom-cur-frame))
|
||||
Loading…
Reference in a new issue