Coder Social home page Coder Social logo

ptrkeys's Introduction

ptrkeys - smooth mouse keys for X11

ptrkeys is a daemon that binds the keyboard to mouse movement, scrolling, and mouse button presses on X. Instead of using acceleration like X's builtin MouseKeys, with ptrkeys speed-multiplier keys are pressed along with directional keys to get faster or more precise movement. This control scheme is based on the observation that most pointing is done by quickly flinging the pointer to a general area before carefully zeroing in on a target. With ptrkeys multiple directional keys can be pressed at once, enabling fluid control of the pointer.

Unfortunately, to be able to chord directions smoothly and get key-release events reliably ptrkeys needs to grab the whole keyboard, which interferes with full-featured desktop environments, such as GNOME 3, that also grab the whole keyboard when interacting with the menubar, system tray, etc. Because of this, ptrkeys is likely only useful with minimalist window managers.

Requirements

Building ptrkeys requires:

  • Xlib header files (Debian: libx11-dev, Arch: libx11)
  • XTEST header files (Debian: libxtst-dev, Arch: libx11)
  • GNU make
  • a C99 compiler

Installation

Edit the Makefile to suit your system and set the install location. Then build and install using GNU make:

make clean install

Configuration

See config.def.h for an annotated configuration example.

X keyboard model

To understand ptrkeys configuration it's necessary to understand a few things about the X keyboard model.

Key Codes, Symbols, and Maps

Popular desktop operating systems have multiple layers of key translation tables, to support interfacing with a wide variety of keyboard hardware and changing keyboard layouts in software. X uses three layers: scancodes, keycodes, and key symbols.

Scan codes: Sent by the keyboard to a computer. Sets of codes evolved along with keyboard interfaces: "Set 1" for IBM XT, "Set 2" for IBM AT, "Set 3" for the IBM 3270 PC. PS/2 keyboards can be configured to send any of these three sets. USB keyboards send another set of scancodes defined in the HID Usage Tables. Scan codes are typically translated to keycodes by the keyboard driver, but applications like X can request raw scancodes and do their own translation. [On Linux, see KDGKBMODE in man console_ioctl.]

Key codes (keycodes): An intermediate hardware-independent set of codes. On Linux keycodes are translated to text and actions by the keyboard driver or X, using a keymap. X and the keyboard driver use different sets of keycodes. X keycodes can be determined using xev.

Key symbols (keysyms): X's term for its "application-level" set of codes. X applications doing text entry can ask the xserver for the string that a keysym corresponds to (eg XK_a -> "a"). Most keysyms are defined in the Xlib header files keysymdef.h and XF86keysym.h.

Key map (keymap): In general a keymap is a table defining the conversion of scan or key codes to a higher-level representation. In documentation about X keymap usually refers to the map of keycodes to keysyms. xmodmap and setxkbmap can be used to change these mappings.

Modifiers

X has 8 modifiers: Shift, Lock, Control, and Mod1 to Mod5, each represented by a bit in the XKeyEvent structure. Only Shift_L and Shift_R can be assigned to the Shift modifier, and likewise for Control. The Lock modifier is interpreted as either capslock or shiftlock depending on the keysym assigned to it: Caps_Lock or Shift_Lock.

According to the Inter-Client Communications Conventions Manual (ICCCM), Mod1 to Mod5 should be interpreted based on the keysyms they're assigned: eg, if Alt_L is assigned to Mod1, then the Mod1 modifier bit represents Alt. Historically some applications have assumed certain modifier bits have a certain interpretation regardless of the keysyms assigned: most commonly interpreting Mod1 as Meta. Instead of depending on a rule few users are aware of or assuming the meaning of a certain modifier bit, ptrkeys requires a modifier bit (one of Mod1Mask...Mod5Mask) to be explicitly specified in its config.h. Masks for modifier bits are defined in X.h, and the bit a key is assigned to can be determined using the state output of xev when pressing the modifier key in question along with a non-modifier key. Eg, state 0x40 corresponds to Mod4:

0100 0000 = 0x40
|||| |||Shift
|||| ||Lock
|||| |Control
|||| Mod1
|||Mod2
||Mod3
|Mod4
Mod5

xmodmap is practical for making small modifications to the keymap and changing modifier assignments.

Grabs

X generally directs keyboard events to the focused window, but a keyboard can be "grabbed" as a whole or on a per-key basis so that its events are sent elsewhere. For example, pressing a key implicitly sets up a single-key grab so the subsequent release event is received by the same window that got the keypress.

ptrkeys doesn't create a window that can be focused, so a single-key grab is necessary to setup a "global hotkey" that can be used to enable ptrkeys by grabbing the entire keyboard and thus "activating" the rest of its configured key bindings. The GRAB option is used in the keys[] definition to make a global hotkey.

Reference

For more details see:

Running

To try ptrkeys out it can simply be run from the command line.

To run ptrkeys in the background for the remainder of an X session, invoke it from a program launcher or disassociate it from a shell; for example:

nohup ptrkeys &> ~/.ptrkeys.log & disown $!

For a more permanent arrangement, if X is being invoked using startx/xinit, run ptrkeys in the background from ~/.xinitrc. If a display manager is being used it's likely necessary to create a custom session; see these instructions for Ubuntu, for example.

Acknowledgements

ptrkeys is heavily influenced by suckless.org's dwm, although I have intentionally diverged from the suckless style guide:

  • I mix declarations and code, because I'm not aware of any downside, it's convenient, and reducing variables' scope is good.
  • I use header guards because I don't want to update every test program's dependencies when the library's dependencies change.
  • I use // comments because they're easier to format and manipulate.
  • I put single-statement if blocks on the same line as the guard because otherwise I'm continually bit by misleading indentation. -Wmisleading-indentation didn't catch the examples I tried.

License

MIT

ptrkeys's People

Contributors

torbiak avatar

Stargazers

Doãn Hiện avatar  avatar Jose C Luna avatar  avatar Val V avatar Francesco Minnocci avatar Akhil Jalagam avatar Daemon+ avatar Noah Weninger avatar Chatchai Saratakij avatar D. Bohdan avatar Bryan Hyshka avatar Will Foran avatar ym555 avatar RajaniKanth Reddy avatar

Watchers

 avatar James Cloos avatar  avatar

ptrkeys's Issues

`MappingNotify` not handled

MappingNotify seems will not returned by XCheckEventMask and never get handled. When that event appears ptrkeys becomes laggy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.