Skip to content

Instantly share code, notes, and snippets.

@CyberShadow
Created March 30, 2016 17:55
Show Gist options
  • Save CyberShadow/6412d11aea64144f8905cc0b8196f38e to your computer and use it in GitHub Desktop.
Save CyberShadow/6412d11aea64144f8905cc0b8196f38e to your computer and use it in GitHub Desktop.
#!/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;
}
@fidergo-stephane-gourichon

This is programmed in language D. To get an executable file, one can install packages gdc (GNU D compiler) and libx11-dev then run gdc -o xorg-show-grabs xorg-show-grabs.d -lX11.

@cpbotha
Copy link

cpbotha commented Jul 30, 2019

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

@MikuChan03
Copy link

Marry me!

@dpflug
Copy link

dpflug commented Mar 20, 2025

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