Author: n/a
Description: n/a
diff -Naurp unclutter.orig/Makefile unclutter/Makefile
--- unclutter.orig/Makefile 2009-10-10 14:35:50.000000000 +0200
+++ unclutter/Makefile 2009-10-10 14:36:53.000000000 +0200
@@ -12,7 +12,7 @@
INSTPGMFLAGS = -c -s
INSTMANFLAGS = -c
TOP_INCLUDES = -I$(INCROOT)
- CDEBUGFLAGS = -O
+ CDEBUGFLAGS = -O2 -g
ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
@@ -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 -Naurp unclutter.orig/unclutter.c unclutter/unclutter.c
--- unclutter.orig/unclutter.c 2009-10-10 14:35:50.000000000 +0200
+++ unclutter/unclutter.c 2009-10-10 14:36:53.000000000 +0200
@@ -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 -Naurp unclutter.orig/unclutter.man unclutter/unclutter.man
--- unclutter.orig/unclutter.man 2009-10-10 14:35:50.000000000 +0200
+++ unclutter/unclutter.man 2009-10-10 14:36:53.000000000 +0200
@@ -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
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.