Code:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
// gcc -Wall focused.c -o focused -lX11 && focused
XTextProperty text;
char *name;
Window get_toplevel_parent(Display * display, Window window)
{
Window parent;
Window root;
Window * children;
unsigned int num_children;
while (1) {
if (0 == XQueryTree(display, window, &root,
&parent, &children, &num_children)) {
fprintf(stderr, "XQueryTree error\n");
abort();
}
if (children)
XFree(children);
if (window == root || parent == root) {
return window;
} else {
// better at grabbing window names
XGetWMName(display, window, &text);
window = parent;
// worse at grabbing window names
XFetchName(display, window, &name);
}
}
}
int main(int argc, char *argv[]) {
Display *display; // 800x480
Window focus, toplevel_parent_of_focus, window, last_window;
XWindowAttributes attr;
int revert, winNum, winPid, winX, winY = 240;
char pidline [64] = "";
char command [64] = "";
char winName [64] = "";
FILE *fpid;
display = XOpenDisplay(NULL);
// svkbd = virtual keyboard
// panel = vertical panel on right side of screen
int svkbd, last_svkbd = 0, panel, last_panel = 0, last_window_x = 0, last_window_y = 0, last_win_x = 0;
while (1) {
XGetInputFocus(display, &focus, &revert);
toplevel_parent_of_focus = get_toplevel_parent(display, focus);
// check if the virtual keyboard is on
pidline[0] = '\0';
fpid = popen("pidof svkbd-en&", "r");
if (fgets(pidline, 64, fpid) != 0)
svkbd = 1;
else
svkbd = 0;
pclose(fpid);
// Check if panel is up
pidline[0] = '\0';
fpid = popen("pidof panel&", "r");
if (fgets(pidline, 64, fpid) != 0)
panel = 1;
else
panel = 0;
pclose(fpid);
// Get focused window
window = (unsigned)toplevel_parent_of_focus;
printf("Name: %s\n", (const char *)text.value);
// Only execute if current changes will affect the virt. keyboard or focused app; don't try to change to the same size
if ((svkbd != last_svkbd || panel != last_panel || window != last_window || attr.width != last_window_x || attr.height != last_window_y) ) {
// Working but inefficient code
/* printf("Change found: %s\n", command);
pidline[0] = '\0';
fpid = popen("xdotool getactivewindow; xdotool getwindowname $(xdotool getactivewindow) &", "r");
fgets(pidline, 64, fpid);
winNum = strtoul(pidline, NULL, 10);
pidline[0] = '\0';
fgets(pidline, 64, fpid);
strcpy(winName, pidline);
winName[strlen(winName) - 1 ] = '\0';
printf("PID: %i name: '%s'\n", winNum, winName);
pclose(fpid);
// This seems to notice the desktop (which is apparently called 'Openbox' but can be different depending on what program is grabbing the screen name
if (strcmp(winName, "Menu") != 0 &&
strcmp(winName, "Openbox") != 0) {*/
if (panel == 1)
winX = 750; // panel = 50 wide (scr. 800-50)
else
winX = 800; // and screen is 800 wide
if (svkbd == 1)
winY = 240; // virt. keyboard is 240 high
else
winY = 480; // screen is 480 high
// Several attempts to stop desktop from getting through
// The code below must not be executed if no window is open in the window manager
if (strcmp(winName, "Openbox") != 0 && text.format == 8 && text.value != NULL && strcmp((const char *)text.value, "") != 0 && strcmp((const char *)text.value, "(null)") != 0 && strcmp((const char *)text.value, "Openbox") != 0 && strcmp((const char *)text.value, "Menu") != 0) {
// Working inefficient code to adjust wndw size
/*snprintf(command, sizeof command, "xdotool windowsize %i %i %i", winNum, winX, winY);
fpid = popen(command, "r");
pclose(fpid);*/
// Effient but non-working code
XGetWindowAttributes(display, toplevel_parent_of_focus, &attr);
// I believe this func. might be causing the
// bad window error when it is executed when no windows are up
XResizeWindow(display, window, winX, winY);
}
// only refresh virtual keyboard if size is to be changed
if (svkbd == 1 && ((last_win_x != winX && last_svkbd == svkbd) || (last_svkbd != svkbd && panel == 1))) {
// Will later use execl call but not apriority atm
if (panel == 1)
fpid = popen("killall svkbd-en; svkbd-en -d -g 750x240 &", "r");
else
fpid = popen("killall svkbd-en; svkbd-en -d -g 800x240 &", "r");
pclose(fpid);
//}
}
}
last_svkbd = svkbd;
last_panel = panel;
last_window = window;
last_window_x = attr.width;
last_window_y = attr.height;
last_win_x = winX;
// sleep one sec (or less if needed)
usleep(1000000);
}
return 0;
}