-
Notifications
You must be signed in to change notification settings - Fork 0
/
maximizer.c
124 lines (104 loc) · 3.88 KB
/
maximizer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xrandr.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Global variable to store the error flag
static int x_error_occurred = 0;
// Custom error handler
int handle_x_errors(Display *display, XErrorEvent *error_event) {
if (error_event->error_code == BadWindow) {
x_error_occurred = 1;
return 0;
}
// else do default error handling
return 1; // Return 0 to ignore the error
}
Window find_window_by_name(Display *display, Window root, const char *window_name) {
Window parent;
Window *children;
unsigned int num_children;
char *window_name_ret = NULL;
Window result = 0;
// Query the tree for children
if (XQueryTree(display, root, &root, &parent, &children, &num_children)) {
for (unsigned int i = 0; i < num_children; i++) {
// Set custom error handler
x_error_occurred = 0;
XSetErrorHandler(handle_x_errors);
XWindowAttributes attrs;
// Check if window is valid using XGetWindowAttributes
// if it throws, skip it
if (XGetWindowAttributes(display, children[i], &attrs) && !x_error_occurred) {
if (XFetchName(display, children[i], &window_name_ret)) {
if (window_name_ret && strstr(window_name_ret, window_name) != NULL) {
XFree(window_name_ret);
result = children[i]; // Found the window
break;
}
XFree(window_name_ret);
}
// Recursive search in child windows
result = find_window_by_name(display, children[i], window_name);
if (result != 0) {
break;
}
} else if (x_error_occurred) {
fprintf(stderr, "Skipped invalid window: 0x%lx\n", children[i]);
}
// Restore the default error handler
XSetErrorHandler(NULL);
}
if (children != NULL) {
XFree(children);
}
}
return result;
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: %s window_name\n", argv[0]);
exit(EXIT_FAILURE);
}
Display *display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Unable to open X display\n");
exit(EXIT_FAILURE);
}
int screen = DefaultScreen(display);
Window root = DefaultRootWindow(display);
int event_base, error_base;
if (!XRRQueryExtension(display, &event_base, &error_base)) {
fprintf(stderr, "XRandR extension not available\n");
exit(EXIT_FAILURE);
}
XRRSelectInput(display, root, RRScreenChangeNotifyMask);
// Initial maximize
Window window = find_window_by_name(display, root, argv[1]);
if (window != 0) {
int screen_width = XDisplayWidth(display, screen);
int screen_height = XDisplayHeight(display, screen);
XResizeWindow(display, window, screen_width, screen_height);
XMoveWindow(display, window, 0, 0);
XFlush(display);
}
XEvent event;
while (1) {
XNextEvent(display, &event);
// Check if we received a screen change notify event
if (event.type == event_base + RRScreenChangeNotify) {
XRRScreenChangeNotifyEvent *screen_change_event = (XRRScreenChangeNotifyEvent *)&event;
int new_width = screen_change_event->width;
int new_height = screen_change_event->height;
Window window = find_window_by_name(display, root, argv[1]);
if (window != 0) {
XResizeWindow(display, window, new_width, new_height);
XMoveWindow(display, window, 0, 0);
XFlush(display);
}
}
}
XCloseDisplay(display);
return 0;
}