summaryrefslogtreecommitdiff
path: root/dwm/patch/banish.c
blob: 60806ab9ad9e2552df5c1c69d24b8f277cc4bc3b (plain)
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
static int cursor_hidden = 0;
/* mouse_x and mouse_y are used to store the actual co-ordinates of the mouse cursor when
 * hidden. These can be manipulated freely, e.g. when using the warp patch, to set a new
 * cursor position for when the cursor is to be revealed again. */
static int mouse_x = 0;
static int mouse_y = 0;
static int xi_opcode;
static unsigned long long last_button_press = 0;

void
genericevent(XEvent *e)
{
	if (e->xcookie.extension != xi_opcode)
		return;

	if (!XGetEventData(dpy, &e->xcookie))
		return;

	switch (e->xcookie.evtype) {
	case XI_RawMotion:
		if (cursor_hidden)
			showcursor(NULL);
		break;
	case XI_RawTouchBegin:
	case XI_RawTouchEnd:
	case XI_RawTouchUpdate:
		if (!cursor_hidden)
			hidecursor(NULL);
		break;
	case XI_RawKeyRelease:
		if (now() - last_button_press > 2000 && !cursor_hidden) {
			hidecursor(NULL);
		}
		break;
	}

	XFreeEventData(dpy, &e->xcookie);
}

void
hidecursor(const Arg *arg)
{
	if (cursor_hidden)
		return;

	XFixesHideCursor(dpy, root);
	if (getrootptr(&mouse_x, &mouse_y)) {
		XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->mx + selmon->mw, selmon->my);
	}

	cursor_hidden = 1;
}

unsigned long long
now(void) {
	struct timespec currentTime;
	clock_gettime(CLOCK_REALTIME, &currentTime);
	return currentTime.tv_sec * 1000LL + currentTime.tv_nsec / 1000000LL;
}

void
showcursor(const Arg *arg)
{
	if (!cursor_hidden)
		return;

	XWarpPointer(dpy, None, root, 0, 0, 0, 0, mouse_x, mouse_y);
	XFixesShowCursor(dpy, root);

	cursor_hidden = 0;
}