Last active
January 18, 2019 07:06
-
-
Save e7/abb35f7521fcd5ee845df9ab461f7534 to your computer and use it in GitHub Desktop.
xwininfo也可以获取窗口id号
This file contains 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
// -*- coding:utf-8-unix; mode:c; -*- | |
/* | |
get the active window on X window system | |
http://k-ui.jp/blog/2012/05/07/get-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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment