Created
March 30, 2016 17:55
-
-
Save CyberShadow/6412d11aea64144f8905cc0b8196f38e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env rdmd | |
module xorg_show_grabs; | |
import std.algorithm; | |
import std.conv; | |
import std.exception; | |
import std.getopt; | |
import std.stdio; | |
import std.string; | |
void main(string[] args) | |
{ | |
const defaultLogFileName = "/var/log/Xorg.0.log"; | |
string logFileName = defaultLogFileName; | |
auto help = getopt(args, | |
"xorg-log", "Path to the Xorg log file, by default: " ~ defaultLogFileName, &logFileName, | |
); | |
if (help.helpWanted) | |
return defaultGetoptPrinter("xorg-show-grabs - Extract and display key grabs from Xorg log in a human-readable way. | |
Usage: | |
1. Run: | |
xdotool key XF86LogGrabInfo | |
2. Run this program. | |
Options: | |
", | |
help.options); | |
bool[string][string] results; | |
string currentClient; | |
bool currentGrab; | |
int currentKey, currentMod; | |
foreach (l; File(logFileName).byLine()) | |
{ | |
auto line = l.findSplit("] ")[2]; | |
if (!line.length) | |
continue; | |
if (line == "Printing all currently registered grabs") | |
results = null; | |
else | |
if (line.skipOver(" Printing all registered grabs of client pid ")) | |
currentClient = line.idup.strip(); | |
else | |
if (line.skipOver(" grab ")) | |
{ | |
currentGrab = false; | |
line.skipUntil(' '); | |
if (!line.startsWith("(core), type 'KeyPress' on window ")) | |
continue; | |
currentGrab = true; | |
} | |
else | |
if (line.skipOver(" device ")) | |
{ | |
if (!line.startsWith("'Virtual core keyboard' (")) | |
currentGrab = false; | |
} | |
else | |
if (line.skipOver(" detail ")) | |
{ | |
currentKey = line.skipUntil(' ').to!int; | |
if (!line.skipOver("(mask 0), modifiersDetail ")) | |
continue; | |
currentMod = line.skipUntil(' ').to!int; | |
} | |
else | |
if (line.skipOver(" owner-events ")) | |
{ | |
if (currentGrab) | |
{ | |
auto key = xModToString(currentMod)~xKeyToString(currentKey); | |
results[currentClient][key] = true; | |
currentGrab = false; | |
} | |
} | |
} | |
foreach (client; results.keys.sort()) | |
{ | |
writefln("%s:", client); | |
foreach (key; results[client].keys.sort()) | |
writefln(" %s", key); | |
} | |
} | |
auto skipUntil(T)(ref T[] s, T c) | |
{ | |
auto i = s.indexOf(c); | |
if (i < 0) | |
{ | |
s = null; | |
return null; | |
} | |
auto result = s[0..i]; | |
s = s[i+1..$]; | |
return result; | |
} | |
pragma(lib, "X11"); | |
import core.stdc.config; | |
struct Display; | |
alias KeyCode = ubyte; | |
alias KeySym = c_ulong; | |
extern(C) Display* XOpenDisplay(const(char)*); | |
extern(C) KeySym XkbKeycodeToKeysym(Display *dpy, KeyCode kc, uint group, uint level); | |
extern(C) char* XKeysymToString(KeySym); | |
string xKeyToString(int key) | |
{ | |
static Display *dpy = null; | |
if (!dpy) | |
dpy = enforce(XOpenDisplay(":0"), "Can't open display!"); | |
KeySym ks = XkbKeycodeToKeysym(dpy, cast(ubyte)key, 0, 0); | |
return XKeysymToString(ks).to!string(); | |
} | |
string xModToString(int mod) | |
{ | |
// 1 2 4 8 0x10 0x20 0x40 0x80 | |
//const string[] names = [ "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"]; | |
//const string[] names = [ "Shift", "Lock", "Control", "Alt" , "Mod2", "Mod3", "Win" , "Mod5"]; | |
const string[] names = [ "Shift", "Lock", "Control", "Mod1(Alt)" , "Mod2", "Mod3", "Mod4(Win)" ,"Mod5"]; | |
string result; | |
foreach (i, name; names) | |
if ((1<<i) & mod) | |
result ~= name ~ " + "; | |
return result; | |
} |
On Arch / Manjaro, gdc
unfortunately does not build anymore:
$ gdc -o xorg-show-grabs xorg-show-grabs.d -lX11 -llto_plugin
gdc: fatal error: -fuse-linker-plugin, but liblto_plugin.so not found
Fortunately, dmd
(the D reference compiler) is even easier:
$ dmd xorg-show-grabs.d
The binary is called xorg-show-grabs
Marry me!
On Arch / Manjaro,
gdc
unfortunately does not build anymore
In case anyone else ends up here, that's because the lto plugin was folded into gdc. You just leave that one off.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is programmed in language D. To get an executable file, one can install packages
gdc
(GNU D compiler) andlibx11-dev
then rungdc -o xorg-show-grabs xorg-show-grabs.d -lX11
.