[dev] [st] [PATCH] Hide X cursor when typing.

From: Colona <colona_AT_ycc.fr>
Date: Mon, 9 Jun 2014 03:38:24 +0200

Add a new configuration variable, xcursorhide, to hide the X cursor when typing
in the terminal. The cursor is displayed again when the mouse is moved.
PointerMotionMask is disabled in bmotion (through xsetpointermotion()) to avoid
high CPU usage when the mouse is moved all over the terminal window.
---
 config.def.h |  3 +++
 st.c         | 33 +++++++++++++++++++++++++++------
 2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/config.def.h b/config.def.h
index 6e2be9a..b8d0d23 100644
--- a/config.def.h
+++ b/config.def.h
_AT_@ -31,6 +31,9 @@ static bool allowaltscreen = true;
 static unsigned int xfps = 120;
 static unsigned int actionfps = 30;
 
+/* hide X cursor when typing */
+static bool xcursorhide = true;
+
 /*
  * blinking timeout (set to 0 to disable blinking) for the terminal blinking
  * attribute.
diff --git a/st.c b/st.c
index 3681776..c4bd034 100644
--- a/st.c
+++ b/st.c
_AT_@ -249,6 +249,8 @@ typedef struct {
 	Draw draw;
 	Visual *vis;
 	XSetWindowAttributes attrs;
+	Cursor cursor, bcursor; /* visible and blank cursors */
+	bool cursorstate; /* is cursor currently visible */
 	int scr;
 	bool isfixed; /* is fixed geometry? */
 	int l, t; /* left and top offset */
_AT_@ -1115,6 +1117,13 @@ void
 bmotion(XEvent *e) {
 	int oldey, oldex, oldsby, oldsey;
 
+	if(!xw.cursorstate) {
+		XDefineCursor(xw.dpy, xw.win, xw.cursor);
+		xw.cursorstate = true;
+		if(!IS_SET(MODE_MOUSEMANY))
+			xsetpointermotion(0);
+	}
+
 	if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
 		mousereport(e);
 		return;
_AT_@ -2998,9 +3007,11 @@ xzoom(const Arg *arg) {
 void
 xinit(void) {
 	XGCValues gcvalues;
-	Cursor cursor;
 	Window parent;
 	pid_t thispid = getpid();
+	XColor xcwhite = {.red = 0xffff, .green = 0xffff, .blue = 0xffff};
+	XColor xcblack = {.red = 0x0000, .green = 0x0000, .blue = 0x0000};
+	Pixmap blankpm;
 
 	if(!(xw.dpy = XOpenDisplay(NULL)))
 		die("Can't open display\n");
_AT_@ -3073,11 +3084,13 @@ xinit(void) {
 		die("XCreateIC failed. Could not obtain input method.\n");
 
 	/* white cursor, black outline */
-	cursor = XCreateFontCursor(xw.dpy, XC_xterm);
-	XDefineCursor(xw.dpy, xw.win, cursor);
-	XRecolorCursor(xw.dpy, cursor,
-		&(XColor){.red = 0xffff, .green = 0xffff, .blue = 0xffff},
-		&(XColor){.red = 0x0000, .green = 0x0000, .blue = 0x0000});
+	xw.cursor = XCreateFontCursor(xw.dpy, XC_xterm);
+	XRecolorCursor(xw.dpy, xw.cursor, &xcwhite, &xcblack);
+	XDefineCursor(xw.dpy, xw.win, xw.cursor);
+	xw.cursorstate = true;
+	blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1);
+	xw.bcursor = XCreatePixmapCursor(xw.dpy, blankpm, blankpm,
+								     &xcblack, &xcblack, 0, 0);
 
 	xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
 	xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
_AT_@ -3533,6 +3546,8 @@ unmap(XEvent *ev) {
 
 void
 xsetpointermotion(int set) {
+	if(!set && !xw.cursorstate)
+		return;
 	MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
 	XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
 }
_AT_@ -3626,6 +3641,12 @@ kpress(XEvent *ev) {
 	Status status;
 	Shortcut *bp;
 
+	if(xcursorhide && xw.cursorstate) {
+		XDefineCursor(xw.dpy, xw.win, xw.bcursor);
+		xsetpointermotion(1);
+		xw.cursorstate = false;
+	}
+
 	if(IS_SET(MODE_KBDLOCK))
 		return;
 
-- 
2.0.0
-- 
Ivan "Colona" Delalande
Received on Mon Jun 09 2014 - 03:38:24 CEST

This archive was generated by hypermail 2.3.0 : Mon Jun 09 2014 - 03:48:07 CEST