Fix XError handling and Display Lock on Event handling

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2026-04-15 16:12:52 +0200
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2026-04-15 16:12:52 +0200
Commit 91fe87974e8c0d02b230fb1218905920154f5af5 (patch)
-rw-r--r-- main.c 2
-rw-r--r-- manager.c 16
-rw-r--r-- switcher.c 4
3 files changed, 17 insertions, 5 deletions
diff --git a/main.c b/main.c
...
67
	while(wm.running) {
67
	while(wm.running) {
68
		XNextEvent(wm.dpy, &wm.ev);
68
		XNextEvent(wm.dpy, &wm.ev);
69
  
69
  
  
70
		XLockDisplay(wm.dpy);
70
		switch (wm.ev.type) {
71
		switch (wm.ev.type) {
71
			case MapRequest:
72
			case MapRequest:
72
				handle_map_request();
73
				handle_map_request();
...
116
				handle_configure_request();
117
				handle_configure_request();
117
				break;
118
				break;
118
		}
119
		}
  
120
		XUnlockDisplay(wm.dpy);
119
	}
121
	}
120
  
122
  
121
	deinit_window_manager();
123
	deinit_window_manager();
...
diff --git a/manager.c b/manager.c
...
586
	changes.sibling = ev->above;
586
	changes.sibling = ev->above;
587
	changes.stack_mode = ev->detail;
587
	changes.stack_mode = ev->detail;
588
  
588
  
  
589
	XErrorHandler old = XSetErrorHandler(ignore_x_error);
589
	XConfigureWindow(wm.dpy, ev->window, ev->value_mask, &changes);
590
	XConfigureWindow(wm.dpy, ev->window, ev->value_mask, &changes);
  
591
	XSync(wm.dpy, False);
  
592
	XSetErrorHandler(old);
  
593
  
590
	log_message(stdout, LOG_DEBUG, "ConfigureRequest for 0x%lx (x=%d, y=%d, w=%d, h=%d)", ev->window, ev->x, ev->y, ev->width, ev->height);
594
	log_message(stdout, LOG_DEBUG, "ConfigureRequest for 0x%lx (x=%d, y=%d, w=%d, h=%d)", ev->window, ev->x, ev->y, ev->width, ev->height);
591
}
595
}
592
  
596
  
...
594
void handle_map_request(void) {
598
void handle_map_request(void) {
595
	Window window = wm.ev.xmaprequest.window;
599
	Window window = wm.ev.xmaprequest.window;
596
	if (window == wm.root) return;
600
	if (window == wm.root) return;
  
601
  
  
602
	XErrorHandler old = XSetErrorHandler(ignore_x_error);
597
  
603
  
598
	// Move window under cursor position and clamps inside the screen bounds.
604
	// Move window under cursor position and clamps inside the screen bounds.
599
	XWindowAttributes check_attr;
605
	XWindowAttributes check_attr;
...
635
	grab_buttons(window);
641
	grab_buttons(window);
636
  
642
  
637
	add_client(window);
643
	add_client(window);
  
644
	
  
645
	XSync(wm.dpy, False);
  
646
	XSetErrorHandler(old);
  
647
  
638
	log_message(stdout, LOG_DEBUG, "Window 0x%lx mapped and grabbed on desktop %d", window, wm.current_desktop);
648
	log_message(stdout, LOG_DEBUG, "Window 0x%lx mapped and grabbed on desktop %d", window, wm.current_desktop);
639
	redraw_widgets();
649
	redraw_widgets();
640
	update_client_list();
650
	update_client_list();
...
972
	if (wm.start.subwindow != None && (wm.start.state & MODKEY)) {
982
	if (wm.start.subwindow != None && (wm.start.state & MODKEY)) {
973
		XDefineCursor(wm.dpy, wm.start.subwindow, None);
983
		XDefineCursor(wm.dpy, wm.start.subwindow, None);
974
  
984
  
975
		// Restore default error handler
985
		// Restore window manager error handler
976
		XSetErrorHandler(NULL);
986
		XSetErrorHandler(x_error_handler);
977
  
987
  
978
		log_message(stdout, LOG_DEBUG, "Restored default cursor on window 0x%lx", wm.start.subwindow);
988
		log_message(stdout, LOG_DEBUG, "Restored window manager cursor on window 0x%lx", wm.start.subwindow);
979
		wm.start.subwindow = None;
989
		wm.start.subwindow = None;
980
	}
990
	}
981
  
991
  
...
diff --git a/switcher.c b/switcher.c
...
109
		// We grab it on the root window. 
109
		// We grab it on the root window. 
110
		XGrabKeyboard(wm.dpy, wm.root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
110
		XGrabKeyboard(wm.dpy, wm.root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
111
  
111
  
112
		// Count clients
112
		// Count clients - allocate extra to handle new windows mapping during this process
113
		int count = 0;
113
		int count = 0;
114
		Client *c = wm.clients;
114
		Client *c = wm.clients;
115
		while (c) {
115
		while (c) {
...
122
			return;
122
			return;
123
		}
123
		}
124
  
124
  
125
		wm.cycle_clients = malloc(sizeof(Window) * count);
125
		wm.cycle_clients = malloc(sizeof(Window) * (count + 10));
126
		wm.cycle_count = 0;
126
		wm.cycle_count = 0;
127
		wm.active_cycle_index = 0;
127
		wm.active_cycle_index = 0;
128
  
128
  
...