Skip to content

Instantly share code, notes, and snippets.

@tmtm
Created January 10, 2022 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmtm/8a68a34d1380e14a0fb29b56c96f9753 to your computer and use it in GitHub Desktop.
Save tmtm/8a68a34d1380e14a0fb29b56c96f9753 to your computer and use it in GitHub Desktop.
X のウィンドウのクラスとタイトルを取得する(Fiddle バージョン)
require 'fiddle/import'
module X11
extend Fiddle::Importer
dlload 'libX11.so'
typealias 'XID', 'unsigned long'
typealias 'Window', 'XID'
typealias 'Status', 'int'
typealias 'Atom', 'unsigned long'
XClassHint = struct(['char *name', 'char *class_name'])
XTextProperty = struct(['unsigned char *value', 'Atom encoding', 'int format', 'unsigned long nitems'])
extern 'Display* XOpenDisplay(char*)'
extern 'int XGetInputFocus(Display*, Window*, int*)'
extern 'int XGetClassHint(Display*, Window, XClassHint*)'
extern 'Status XQueryTree(Display*, Window, Window*, Window*, Window**, unsigned int*)'
extern 'int XFree(void*)'
extern 'Status XGetWMName(Display*, Window, XTextProperty*)'
extern 'int Xutf8TextPropertyToTextList(Display*, XTextProperty*, char***, int*)'
extern 'void XFreeStringList(char**)'
end
display = X11.XOpenDisplay(nil)
raise "Cannot open display: #{ENV['DISPLAY']}" if display.null?
win_buf = ' '*X11.sizeof('Window')
revert_to = ' '*X11.sizeof('unsigned long')
root = ' '*X11.sizeof('Window')
parent = ' '*X11.sizeof('Window')
children = ' '*X11.sizeof('void*')
nchildren = ' '*X11.sizeof('unsigned int')
loop do
X11.XGetInputFocus(display, win_buf, revert_to)
window = win_buf.unpack1('L')
class_hint = X11::XClassHint.malloc
while window > 0
X11.XGetClassHint(display, window, class_hint)
X11.XQueryTree(display, window, root, parent, children, nchildren)
children_ptr = Fiddle::Pointer[children].ptr
X11.XFree(children_ptr) unless children_ptr.null?
break unless class_hint.name.null? && class_hint.class_name.null?
window = parent.unpack1('L')
end
win_class = class_hint.class_name.to_s
prop = X11::XTextProperty.malloc
prop.encoding = 1
X11.XGetWMName(display, window, prop)
text_list = ' '*X11.sizeof('void*')
count = ' '*X11.sizeof('int*')
X11.Xutf8TextPropertyToTextList(display, prop, text_list, count)
title = Fiddle::Pointer[text_list].ptr.ptr.to_s.force_encoding('utf-8')
p [win_class, title]
X11.XFree(class_hint.name) unless class_hint.name.null?
X11.XFree(class_hint.class_name) unless class_hint.class_name.null?
X11.XFreeStringList(Fiddle::Pointer[text_list].ptr)
sleep 0.1
end
@tmtm
Copy link
Author

tmtm commented Jan 10, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment