Skip to content

Instantly share code, notes, and snippets.

@kui

kui/gist:2622504

Last active Jul 17, 2020
Embed
What would you like to do?
get the active window on X window system.
// -*- coding:utf-8-unix; mode:c; -*-
//
// get the active window on X window system
//
#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
#include <X11/Xlib.h> // `apt-get install libx11-dev`
#include <X11/Xmu/WinUtil.h> // `apt-get install libxmu-dev`
Bool xerror = False;
Display* open_display(){
printf("connecting X server ... ");
Display* d = XOpenDisplay(NULL);
if(d == NULL){
printf("fail\n");
exit(1);
}else{
printf("success\n");
}
return d;
}
int handle_error(Display* display, XErrorEvent* error){
printf("ERROR: X11 error\n");
xerror = True;
return 1;
}
Window get_focus_window(Display* d){
Window w;
int revert_to;
printf("getting input focus window ... ");
XGetInputFocus(d, &w, &revert_to); // see man
if(xerror){
printf("fail\n");
exit(1);
}else if(w == None){
printf("no focus window\n");
exit(1);
}else{
printf("success (window: %d)\n", (int)w);
}
return w;
}
// get the top window.
// a top window have the following specifications.
// * the start window is contained the descendent windows.
// * the parent window is the root window.
Window get_top_window(Display* d, Window start){
Window w = start;
Window parent = start;
Window root = None;
Window *children;
unsigned int nchildren;
Status s;
printf("getting top window ... \n");
while (parent != root) {
w = parent;
s = XQueryTree(d, w, &root, &parent, &children, &nchildren); // see man
if (s)
XFree(children);
if(xerror){
printf("fail\n");
exit(1);
}
printf(" get parent (window: %d)\n", (int)w);
}
printf("success (window: %d)\n", (int)w);
return w;
}
// search a named window (that has a WM_STATE prop)
// on the descendent windows of the argment Window.
Window get_named_window(Display* d, Window start){
Window w;
printf("getting named window ... ");
w = XmuClientWindow(d, start); // see man
if(w == start)
printf("fail\n");
printf("success (window: %d)\n", (int) w);
return w;
}
// (XFetchName cannot get a name with multi-byte chars)
void print_window_name(Display* d, Window w){
XTextProperty prop;
Status s;
printf("window name:\n");
s = XGetWMName(d, w, &prop); // see man
if(!xerror && s){
int count = 0, result;
char **list = NULL;
result = XmbTextPropertyToTextList(d, &prop, &list, &count); // see man
if(result == Success){
printf("\t%s\n", list[0]);
}else{
printf("ERROR: XmbTextPropertyToTextList\n");
}
}else{
printf("ERROR: XGetWMName\n");
}
}
void print_window_class(Display* d, Window w){
Status s;
XClassHint* class;
printf("application: \n");
class = XAllocClassHint(); // see man
if(xerror){
printf("ERROR: XAllocClassHint\n");
}
s = XGetClassHint(d, w, class); // see man
if(xerror || s){
printf("\tname: %s\n\tclass: %s\n", class->res_name, class->res_class);
}else{
printf("ERROR: XGetClassHint\n");
}
}
void print_window_info(Display* d, Window w){
printf("--\n");
print_window_name(d, w);
print_window_class(d, w);
}
int main(void){
Display* d;
Window w;
// for XmbTextPropertyToTextList
setlocale(LC_ALL, ""); // see man locale
d = open_display();
XSetErrorHandler(handle_error);
// get active window
w = get_focus_window(d);
w = get_top_window(d, w);
w = get_named_window(d, w);
print_window_info(d, w);
}
@rr-

This comment has been minimized.

Copy link

@rr- rr- commented Jul 19, 2015

@fusir

This comment has been minimized.

Copy link

@fusir fusir commented Dec 25, 2017

Do you know what package for pkg-config will make it able to compile?

@rbreaves

This comment has been minimized.

Copy link

@rbreaves rbreaves commented Jan 30, 2020

I am also sad to his blog post on this having disappeared.

@cxw42

This comment has been minimized.

Copy link

@cxw42 cxw42 commented Apr 21, 2020

@kui Thank you for this code! What is the license?

@kui

This comment has been minimized.

Copy link
Owner Author

@kui kui commented Apr 22, 2020

http://k-ui.jp/blog/2012/05/07/get-active-window-on-x-window-system/ might be missed from my blog... and I can't remember it. I removed it from this gist.

@cxw42 I'm not going to claim a license for this code. Please feel free to use it.

@cxw42

This comment has been minimized.

Copy link

@cxw42 cxw42 commented Apr 22, 2020

@kui Thank you!

@rbreaves

This comment has been minimized.

Copy link

@rbreaves rbreaves commented Apr 22, 2020

@kui Also giving you my thanks, I've already been using it as a base for Kinto. It looks a good deal different at this point and I am moving on to re-using xkeysnail and contributing code to that project to make it a better replacement for my own use case scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.