File: 01-conglomeration.patch

package info (click to toggle)
unclutter 8-26
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 352 kB
  • sloc: ansic: 1,758; makefile: 170; sh: 81
file content (287 lines) | stat: -rw-r--r-- 8,626 bytes parent folder | download
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
From: Axel Beckert <abe@debian.org>
Date: Sat, 20 Sep 2025 22:09:40 +0100
Subject: n/a

---
 Makefile      |   5 +--
 unclutter.c   | 103 +++++++++++++++++++++++++++++++++++++++++++++++-----------
 unclutter.man |  30 ++++++++++++++---
 3 files changed, 113 insertions(+), 25 deletions(-)

diff --git a/Makefile b/Makefile
index 3c7b93c..0e6c1d1 100644
--- a/Makefile
+++ b/Makefile
@@ -21,13 +21,13 @@
            RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
          IRULESRC = $(CONFIGDIR)
         IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
-           BINDIR = $(DESTDIR)/usr/bin/X11
+           BINDIR = $(DESTDIR)/usr/bin
           INCROOT = $(DESTDIR)/usr/include
           MANPATH = $(DESTDIR)/usr/catman/x11_man
     MANSOURCEPATH = $(MANPATH)/man
            MANDIR = $(MANSOURCEPATH)1
             IMAKE = imake
-             XLIB = $(EXTENSIONLIB)  -lX11
+             XLIB = $(EXTENSIONLIB) -L/usr/X11R6/lib -lX11
 
   LOCAL_LIBRARIES = $(XLIB)
 
@@ -43,6 +43,7 @@ unclutter: $(OBJS) $(DEPLIBS)
 	$(LKED) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
 
 install:: unclutter
+	$(INSTALL) -d $(BINDIR)
 	$(INSTALL) -c $(INSTPGMFLAGS)   unclutter $(BINDIR)
 install.man:: unclutter.man
 	$(INSTALL) -c $(INSTMANFLAGS) unclutter.man $(MANDIR)/unclutter.1
diff --git a/unclutter.c b/unclutter.c
index 23bb99b..9d0302c 100644
--- a/unclutter.c
+++ b/unclutter.c
@@ -25,6 +25,11 @@
 #include <X11/Xproto.h>
 #include <stdio.h>
 #include "vroot.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <regex.h>
 
 char *progname;
 pexit(str)char *str;{
@@ -43,9 +48,23 @@ usage(){
  	-root	       		apply to cursor on root window too\n\
 	-onescreen		apply only to given screen of display\n\
  	-visible       		ignore visibility events\n\
- 	-noevents      		dont send pseudo events\n\
-	-not names...		dont apply to windows whose wm-name begins.\n\
-				(must be last argument)");
+ 	-noevents      		don't send pseudo events\n\
+	-regex			name or class below is a regular expression\n\
+	-not names...		don't apply to windows whose wm-name begins.\n\
+				(must be last argument)\n\
+	-notname names...	same as -not names...\n\
+	-notclass classes...    don't apply to windows whose wm-class begins.\n\
+				(must be last argument, cannot be used with\n\
+				-not or -notname)");
+}
+
+static void dsleep(float t)
+{
+    struct timeval tv;
+    assert(t >= 0);
+    tv.tv_sec = (int) t;
+    tv.tv_usec = (t - tv.tv_sec) * 1000000;
+    select(0, NULL, NULL, NULL, &tv);
 }
 
 #define ALMOSTEQUAL(a,b) (abs(a-b)<=jitter)
@@ -66,27 +85,46 @@ XErrorEvent *error;
 	(*defaulthandler)(display,error);
 }
 
-char **names;	/* -> argv list of names to avoid */
+char **names = 0;	/* -> argv list of names to avoid */
+char **classes = 0;     /* -> argv list of classes to avoid */
+regex_t *nc_re = 0;     /* regex for list of classes/names to avoid */
 
 /*
- * return true if window has a wm_name and the start of it matches
- * one of the given names to avoid
+ * return true if window has a wm_name (class) and the start of it matches
+ * one of the given names (classes) to avoid
  */
 nameinlist(display,window)
 Display *display;
 Window window;
 {
     char **cpp;
-    char *name;
+    char *name = 0;
 
-    if(names==0)return 0;
-    if(XFetchName (display, window, &name)){
-	for(cpp = names;*cpp!=0;cpp++){
-	    if(strncmp(*cpp,name,strlen(*cpp))==0)
-		break;
+    if(names)
+	XFetchName (display, window, &name);
+    else if(classes){
+	XClassHint *xch = XAllocClassHint();
+	if(XGetClassHint (display, window, xch))
+	    name = strdup(xch->res_class);
+	if(xch)
+	    XFree(xch);
+    }else
+	return 0;
+
+    if(name){
+	if(nc_re){
+	    if(!regexec(nc_re, name, 0, 0, 0)) {
+		XFree(name);
+		return 1;
+	    }
+	}else{
+	    for(cpp = names!=0 ? names : classes;*cpp!=0;cpp++){
+		if(strncmp(*cpp,name,strlen(*cpp))==0)
+		    break;
+	    }
+	    XFree(name);
+	    return(*cpp!=0);
 	}
-	XFree(name);
-	return(*cpp!=0);
     }
     return 0;
 }	
@@ -120,8 +158,9 @@ Window root;
 main(argc,argv)char **argv;{
     Display *display;
     int screen,oldx = -99,oldy = -99,numscreens;
-    int doroot = 0, jitter = 0, idletime = 5, usegrabmethod = 0, waitagain = 0,
-	dovisible = 1, doevents = 1, onescreen = 0;
+    int doroot = 0, jitter = 0, usegrabmethod = 0, waitagain = 0,
+        dovisible = 1, doevents = 1, onescreen = 0;
+    float idletime = 5.0;
     Cursor *cursor;
     Window *realroot;
     Window root;
@@ -133,7 +172,7 @@ main(argc,argv)char **argv;{
 	if(strcmp(*argv,"-idle")==0){
 	    argc--,argv++;
 	    if(argc<0)usage();
-	    idletime = atoi(*argv);
+	    idletime = atof(*argv);
 	}else if(strcmp(*argv,"-keystroke")==0){
 	    idletime = -1;
 	}else if(strcmp(*argv,"-jitter")==0){
@@ -152,17 +191,39 @@ main(argc,argv)char **argv;{
 	    onescreen = 1;
 	}else if(strcmp(*argv,"-visible")==0){
 	    dovisible = 0;
-	}else if(strcmp(*argv,"-not")==0){
+	}else if(strcmp(*argv,"-regex")==0){
+	    nc_re = (regex_t *)malloc(sizeof(regex_t));
+	}else if(strcmp(*argv,"-not")==0 || strcmp(*argv,"-notname")==0){
 	    /* take rest of srg list */
 	    names = ++argv;
 	    if(*names==0)names = 0;	/* no args follow */
 	    argc = 0;
+	}else if(strcmp(*argv,"-notclass")==0){
+	    /* take rest of arg list */
+	    classes = ++argv;
+	    if(*classes==0)classes = 0;	/* no args follow */
+	    argc = 0;
 	}else if(strcmp(*argv,"-display")==0 || strcmp(*argv,"-d")==0){
 	    argc--,argv++;
 	    if(argc<0)usage();
 	    displayname = *argv;
 	}else usage();
     }
+    /* compile a regex from the first name or class */
+    if(nc_re){
+	if(names || classes){
+	    if (regcomp(nc_re, (names != 0 ? *names : *classes),
+			REG_EXTENDED | REG_NOSUB)) { /* error */
+		free(nc_re);
+		names = classes = 0;
+		nc_re = 0;
+	    }
+	}else{ /* -regex without -not... ... */
+	    free(nc_re);
+	    nc_re = 0;
+	}
+    }
+
     display = XOpenDisplay(displayname);
     if(display==0)pexit("could not open display");
     numscreens = ScreenCount(display);
@@ -251,7 +312,7 @@ main(argc,argv)char **argv;{
 		}
 	    }
 	    if(idletime>=0)
-		sleep(idletime);
+		dsleep(idletime);
 	}
 	/* wait again next time */
 	if(waitagain)
@@ -270,6 +331,10 @@ main(argc,argv)char **argv;{
 			ALMOSTEQUAL(rootx,event.xmotion.x) &&
 			ALMOSTEQUAL(rooty,event.xmotion.y)));
 		XUngrabPointer(display, CurrentTime);
+	    }else{
+		/* go to sleep to prevent tight loops */
+		if(idletime>=0)
+			dsleep(idletime);
 	    }
 	}else{
 	    XSetWindowAttributes attributes;
diff --git a/unclutter.man b/unclutter.man
index 93c9f28..11acec3 100644
--- a/unclutter.man
+++ b/unclutter.man
@@ -1,5 +1,5 @@
 .\"unclutter man
-.TH UNCLUTTER 1X
+.TH UNCLUTTER 1
 .SH NAME
 unclutter \- remove idle cursor image from screen
 .SH SYNOPSIS
@@ -17,8 +17,12 @@ unclutter
 .RB [ -reset ]
 .RB [ -root ]
 .RB [ -onescreen ]
-.RB [ -not ]
-.I "name ...
+.RB [ -visible ]
+.RB [ -regex ]
+.RB [ -not | -notname
+.IR name " " ... ]
+.RB [ -notclass
+.IR class " " ... ]
 .SH DESCRIPTION
 .B unclutter
 removes the cursor image from the screen so that it does not
@@ -34,7 +38,7 @@ is followed by the display to open.
 .TP
 -idle
 is followed by the number of seconds between polls for idleness.
-The default is 5.
+The default is 5. Supports subsecond idle times.
 .TP
 -keystroke
 tells
@@ -75,12 +79,30 @@ restricts unclutter to the single screen specified as display,
 or the default screen for the display.
 Normally, unclutter will unclutter all the screens on a display.
 .TP
+-visible
+ignore visibility events (does not apply to -grab).
+If the cursor never gets hidden, despite a generous -jitter value,
+try this option
+.TP
 -not
 is followed by a list of window names where the cursor should not be
 removed.
 The first few characters of the WM_NAME property on the window need
 to match one the listed names.
 This argument must be the last on the command line.
+.TP
+-notname
+is exactly the same as -not
+.TP
+-notclass
+is similar to -notname, except that the WM_CLASS property of the window is used.
+This argument must be the last on the command line, and so cannot be used
+with -not or -notname.
+.TP
+-regex
+treats the first name or class (see above) as a regular expression.
+This means that `` -regex -not foo bar '' will not work as expected; instead
+use `` -regex -not 'foo|bar' ''.
 .SH LIMITATIONS
 The -keystroke option may not work (that is, the cursor will not
 disappear) with clients that request KeyRelease events.