You are not logged in.
ok, so in another post here I decided to throw together a little daemon app that will make all windows transparent and the focused window will be opaque...
the problem is that I did it at work, and don't have the internet at home - so I have no XLib/gcc to compile against...
my request to someone out there - make this work... it'll be a fun little app, and may need some performance tweaking, but it's only 150 lines... (it could probably use some more VOUT() macro calls...)
without further ado transfocus.c (Makefile below)
/*
transfocus.c - Aaron Griffin
This code is provided under no license whatsoever - use
it as you will, but you're not allowed to sue me for doing so
*/
#define PROG_NAME "transfocus"
#define PROG_VERSION "0.1"
#define OPAQUE 0xffffffff
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#define VOUT(msg,args...) {if(verbose) printf(msg,args...);}
void usage()
{
fprintf(stderr,
"usage: %s [-options ...] [1 > opacity > 0, default=0.5]n"
"options:n"
" -h, --help display this messagen"
" -d, --daemon run as a daemon (background)n"
" -t, --timeout <int> timeout value for check in ms [default=100]n"
" --verbose verbose output (debug)n"
" -v, --version print version numbern", PROG_NAME);
exit(1);
}
Display disp;
Atom trans_prop;
bool verbose;
static int x_error_handler(Display *dpy, XErrorEvent *error)
{
char buf[1024];
XGetErrorText(disp, error->error_code, buf, 1024);
fprintf(stderr, ":: X Error - %s (%d)n", buf, error->request_code);
return 0;
}
unsigned int get_window_trans(Window w)
{
Atom actual;
int format;
unsigned long n, b;
unsigned char *val;
unsigned int ret;
XGetWindowProperty(disp, w, trans_prop, 0L, 1L, False, XA_CARDINAL,
&actual, &format, &n, &b, (unsigned char**)&val);
if(data != None)
{
memcpy(&ret, val, sizeof(unsigned int));
XFree((void*)val);
}
else
{
VOUT(":: Bad Transparency Property Value... setting opaque");
ret = OPAQUE;
}
return ret;
}
void set_window_trans(Window w, unsigned int opacity)
{
if(opacity == OPAQUE) XDeleteProperty(disp, w, trans_prop);
else
XChangeProperty(disp, w, trans_prop, XA_CARDINAL, 32,
PropModeReplace, (unsigned char*)&opacity, 1L);
XSync(dpy, False);
}
int main(int argc, char **argv)
{
bool daemonize = false;
float opacity_level = 0.5;
int o, idx=0, timeout=100, focused_state, num_children;
unsigned int opacity;
Window root, focused, dummy, *children;
struct option opts[] =
{
{"help",0,NULL,'h'},
{"daemon",0,NULL,'d'},
{"timeout",1,NULL,'t'},
{"verbose",0,NULL,1001},
{"version",0,NULL,'v'},
{0,0,0,0}
};
while ((o = getopt_long(argc, argv, "thpci:n:vm:x:12",opts,&idx)) != -1)
{
switch(o)
{
case 1001: verbose = true;
case 'h': usage(); return 1;
case 't': daemonize = true; break;
case 't': timeout = atoi(optarg); break;
case 'v': fprintf(stderr,"version: %sn",VERSIONSTR); exit(1); break;
default: usage() return 1;
}
}
if(optind < argc) opacity_level = atof(argv[optind]);
else
{
usage();
return 1;
}
if(daemonize)
{
VOUT(":: deamonizing process - don't use these options together...");
daemon(0,0);
}
VOUT(":: initializing X variables");
disp = XOpenDisplay(NULL); //use environment variable
root = XRootWindow(disp,XDefaultScreen(disp));
XSetErrorHandler(x_error_handler);
trans_prop = XInternAtom(disp, "_NET_WM_WINDOW_OPACITY", False);
opacity = (unsigned int)(opacity_level * OPAQUE);
VOUT(":: window opacity setting at %d",opacity);
while(true)
{
XGetInputFocus(disp, &focused, &focus_state);
set_window_trans(focused, OPAQUE);
if(XQueryTree(disp, root, &dummy, &dummy, &children, &num_children))
{
VOUT(":: Found %d child windows", num_children);
for(int i=0; i<n; ++i)
{
if(children[i] != focused)
{
unsigned int trans = get_window_trans(children[i]);
set_window_trans(children[i],opacity);
}
}
if(children) XFree((char*)children);
}
sleep(timeout);
}
return 0;
}
Makefile:
LIBS=`pkg-config --libs xcomposite xfixes xdamage xrender` -lm
INCS=`pkg-config --cflags xcomposite xfixes xdamage xrender`
.c.o:
$(CC) $(CFLAGS) $(INCS) -c $*.c
OBJS=transfocus.o
transfocus: $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
clean:
rm -f $(OBJS) transfocus
Offline
Yeah, I like your efforts. I gave up on transparency for that same very reason, configurability. Trying to read my focused window full of source code is hard when it's not opaque. Even applying modest degrees of translucency to that window didn't help. I got tired of jacking with it and turned it off altogther.
I was hoping with the newest XFCE release, they would have a similiar feature already integrated in there, but they don't.
I hope you get it working.
Offline
the nice thing is that this should work with any WM - when I discovered how simple transparency and things of that nature were to work with, it was a great moment...
maybe next I'll take a look at drop shadows...
Offline
I looked at it and right now I don't have time to make it work but I found a few issuses so far.
bool verbose;
As far as I know bool is not part of c its a feature of c++.
In get_window_trans() if(data != None) but data does not seem to be declared.
Also the make file $(CC) is not declared so it won't work.
It looks like an interesting project and I definatly want to try it. I will have to look at it more this weekend.
Offline
Hi phrakture,
I tried setting up a transfocus.c and a makefile as supplied. When the makefile is opened in Gvim, the line starting $(cc).... is highlighted in red. So is the very las line. When I ran make, it said;
makefile:5: *** missing separator. Stop.
I'm new to this so do you have any ideas??
Jim
Offline
Offline
When the makefile is opened in Gvim, the line starting $(cc).... is highlighted in red. So is the very las line. When I ran make, it said;
makefile:5: *** missing separator. Stop.
1. As kill suggested, add:
CC=gcc
at the top of the file.
2. Make sure that the indentations are tabs NOT spaces. make is very fussy about this.
Offline
cam - sure that is not just the window title?
Offline
Ok, I tried the changes suggested and I got a page full of errors:
[root@Berettaj ~]# make
make: *** No targets specified and no makefile found. Stop.
[root@Berettaj ~]# cd jimtest/
[root@Berettaj jimtest]# MAKE
bash: MAKE: command not found
[root@Berettaj jimtest]# make
gcc `pkg-config --cflags xcomposite xfixes xdamage xrender` -c transfocus.c
transfocus.c:37: error: parse error before "verbose"
transfocus.c:37: warning: data definition has no type or storage class
transfocus.c: In function `x_error_handler':
transfocus.c:43: error: `disp' has an incomplete type
transfocus.c: In function `get_window_trans':
transfocus.c:57: error: `disp' has an incomplete type
transfocus.c:59: error: `data' undeclared (first use in this function)
transfocus.c:59: error: (Each undeclared identifier is reported only once
transfocus.c:59: error: for each function it appears in.)
transfocus.c:66: error: parse error before '...' token
transfocus.c: In function `set_window_trans':
transfocus.c:75: error: `disp' has an incomplete type
transfocus.c:78: error: `disp' has an incomplete type
transfocus.c:80: error: `dpy' undeclared (first use in this function)
transfocus.c: In function `main':
transfocus.c:85: error: `bool' undeclared (first use in this function)
transfocus.c:85: error: parse error before "daemonize"
transfocus.c:105: error: `true' undeclared (first use in this function)
transfocus.c:107: error: `daemonize' undeclared (first use in this function)
transfocus.c:108: error: duplicate case value
transfocus.c:107: error: previously used here
transfocus.c:109: error: `VERSIONSTR' undeclared (first use in this function)
transfocus.c:110: error: parse error before "return"
transfocus.c:123: error: parse error before '...' token
transfocus.c:127: error: parse error before '...' token
transfocus.c:128: error: `disp' has an incomplete type
transfocus.c:129: error: `disp' has an incomplete type
transfocus.c:129: error: `disp' has an incomplete type
transfocus.c:131: error: `disp' has an incomplete type
transfocus.c:133: error: parse error before '...' token
transfocus.c:137: error: `focus_state' undeclared (first use in this function)
transfocus.c:137: error: `disp' has an incomplete type
transfocus.c:140: error: `disp' has an incomplete type
transfocus.c:142: error: parse error before '...' token
transfocus.c:143: error: 'for' loop initial declaration used outside C99 mode
transfocus.c:143: error: `n' undeclared (first use in this function)
transfocus.c: At top level:
transfocus.c:35: error: storage size of `disp' isn't known
make: *** [transfocus.o] Error 1
[root@Berettaj jimtest]#
This is way beyond me.
Jim
Offline
I've been working on it like it said. First of all it portions are c++ and needs to be compiled with g++. I've gotten it to compile but it dosn't work. For some reason VOUT(":: window opacity setting at %d",opacity); outputs some very large numbers... I'm done for today and will work on it some more tomorrow.
Offline
cam was dead right - fluxbox sets different focus and unfocus transparencies out of the box
Offline
i just edited the code - as it couldn't compile out of the box, there were errors all over the code.
but as i don't know the xlib api and didn't had time to look into it - i can't say if it's working correctly, but it does now compile with gcc;
and i disabled the VOUT macro, because i'm not that competent with macros and there was an error, too.
/*
transfocus.c - Aaron Griffin
This code is provided under no license whatsoever - use
it as you will, but you're not allowed to sue me for doing so
*/
#define PROG_NAME "transfocus"
#define VERSION "0.1"
#define OPAQUE 0xffffffff
typedef unsigned char BOOL;
enum{
FALSE = 0,
TRUE = 1
};
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#define VOUT(msg,args...) {if(verbose) printf(msg,args...);}
void usage()
{
fprintf(stderr,
"usage: %s [-options ...] [1 > opacity > 0, default=0.5]n"
"options:n"
" -h, --help display this messagen"
" -d, --daemon run as a daemon (background)n"
" -t, --timeout <int> timeout value for check in ms [default=100]n"
" --verbose verbose output (debug)n"
" -v, --version print version numbern", PROG_NAME);
exit(1);
}
Display *display = NULL;
Atom trans_prop;
BOOL verbose = FALSE;
static int x_error_handler(Display *dpy, XErrorEvent *error)
{
char buf[1024];
XGetErrorText(display, error->error_code, buf, 1024);
fprintf(stderr, ":: X Error - %s (%d)n", buf, error->request_code);
return 0;
}
unsigned int get_window_trans(Window wnd){
Atom actual;
int format;
unsigned long n;
unsigned long b;
unsigned char* val;
unsigned int ret;
XGetWindowProperty(display, wnd, trans_prop, 0L, 1L, FALSE, XA_CARDINAL,
&actual, &format, &n, &b, (unsigned char**)&val);
if(val != None){
memcpy(&ret, val, sizeof(unsigned int));
XFree((void*)val);
}else{
//VOUT(":: Bad Transparency Property Value... setting opaque");
ret = OPAQUE;
}
return ret;
}
void set_window_trans(Window w, unsigned int opacity)
{
if(opacity == OPAQUE) XDeleteProperty(display, w, trans_prop);
else
XChangeProperty(display, w, trans_prop, XA_CARDINAL, 32,
PropModeReplace, (unsigned char*)&opacity, 1L);
XSync(display, FALSE);
}
int main(int argc, char **argv)
{
BOOL daemonize = FALSE;
float opacity_level = 0.5;
int o = -1;
int idx = 0;
int timeout = 100;
int focus_state = 0;
int num_children = 0;
int i = 0;
unsigned int opacity = 0;
Window root = 0;
Window focused = 0;
Window dummy = 0;
Window *children = NULL;
struct option opts[] =
{
{"help",0,NULL,'h'},
{"daemon",0,NULL,'d'},
{"timeout",1,NULL,'t'},
{"verbose",0,NULL,1001},
{"version",0,NULL,'v'},
{0,0,0,0}
};
while ((o = getopt_long(argc, argv, "thpci:n:vm:x:12",opts,&idx)) != -1){
switch(o){
case 1001:
verbose = TRUE;
case 'h':
usage();
return 1;
case 'd':
daemonize = TRUE;
break;
case 't':
timeout = atoi(optarg);
break;
case 'v':
fprintf(stderr,"version: %sn",VERSION);
exit(1);
break;
default:
usage();
return 1;
}
}
if(optind < argc) opacity_level = atof(argv[optind]);
else{
usage();
return 1;
}
if(daemonize)
{
//VOUT(":: deamonizing process - don't use these options together...");
daemon(0,0);
}
//VOUT(":: initializing X variables");
display = XOpenDisplay(NULL); //use environment variable
root = XRootWindow(display,XDefaultScreen(display));
XSetErrorHandler(x_error_handler);
trans_prop = XInternAtom(display, "_NET_WM_WINDOW_OPACITY", FALSE);
opacity = (unsigned int)(opacity_level * OPAQUE);
//VOUT(":: window opacity setting at %d",opacity);
while(TRUE){
XGetInputFocus(display, &focused, &focus_state);
set_window_trans(focused, OPAQUE);
if(XQueryTree(display, root, &dummy, &dummy, &children, &num_children)){
//VOUT(":: Found %d child windows", num_children);
for(; i< num_children; ++i){
if(children[i] != focused){
unsigned int trans = get_window_trans(children[i]);
set_window_trans(children[i],opacity);
}
}
if(children)
XFree((char*)children);
}
sleep(timeout);
}
return 0;
}
LIBS=`pkg-config --libs xcomposite xfixes xdamage xrender` -lm
INCS=`pkg-config --cflags xcomposite xfixes xdamage xrender`
CC=gcc
OBJS=transfocus.o
all: transfocus
*.o:
$(CC) $(CFLAGS) $(INCS) -c $*.c
transfocus: $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
clean:
rm -f $(OBJS) transfocus
Offline
Trying 'make' with files as supplied, I get;
]# make
makefile:10: *** missing separator. Stop.
Thanks,
Jim
Offline
Trying 'make' with files as supplied, I get;
]# make
makefile:10: *** missing separator. Stop.Thanks,
Jim
Same error here
Kaleph
jabber: kaleph@jabber.org
Offline
there is some error with the code to set the transparency of the focus window. for me all windows are translucent.
Offline
@ KalephOne and MillTek: try to compile without make, type:
gcc `pkg-config --cflags xcomposite xfixes xdamage xrender` -c transfocus.c
gcc -o transfocus transfocus.o `pkg-config --libs xcomposite xfixes xdamage xrender` -lm
As I couldn't find the problem with the old code, I did a complete rewrite - I think this way it's much cleaner. But it does make only the window under the cursor opaque not the real focuse window, because I couldn't get it to work.
/*
transfocus.c by cmp
based on transfocus by Aaron Griffin
currently no real focus is used but simple the mouse pointer
this code is provided under no license whatsoever - use
it as you will, but you're not allowed to sue me for doing so
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
// constants
const char* PROG_NAME = "transfocus";
const char* VERSION = "0.1";
const char* OPACITY = "_NET_WM_WINDOW_OPACITY";
const unsigned OPAQUE = 0xffffffff;
// some typedefs
typedef unsigned int uint;
typedef unsigned char BOOL;
enum{ FALSE = 0, TRUE = -1 };
enum{ PFATAL_ERROR, PERROR, PMESSAGE, PINFO };
// global vars
struct{
Display* display;
Window root;
int screen;
int timeout;
Atom transparency;
BOOL verbose;
BOOL daemon;
float ratio;
}global;
// helper
#define Print(type, str, ...)
if(global.verbose || type != PINFO) printf(str, ## __VA_ARGS__);
// logic
static int x_error_handler(Display *dpy, XErrorEvent *error)
{
char buf[1024];
XGetErrorText(global.display, error->error_code, buf, 1024);
Print(PERROR, ":: X Error - %s (%d)n", buf, error->request_code);
return 0;
}
Window GetFocusWindow(){
Window target;
Window tmp;
int rx, ry;
int wx, wy;
uint mask;
XQueryPointer(global.display, global.root, &tmp, &target, &rx, &ry, &wx, &wy, &mask);
return target;
}
BOOL SetTransparency(uint opaque, uint translucent){
Window target = GetFocusWindow();
Window *children = NULL;
Window dummy = 0;
int num_children = 0;
int current = 0;
if(XQueryTree(global.display, global.root, &dummy, &dummy, &children, &num_children)){
Print(PINFO, ":: found %d childrenn", num_children);
for(current = 0; current < num_children; current++){
if(children[current] != target){
XChangeProperty(global.display, children[current],
global.transparency, XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &translucent, 1L);
}
}
if(children) XFree((char*)children);
}
// delete the property for the target
XDeleteProperty (global.display, target, global.transparency);
return TRUE;
}
void usage()
{
Print(PMESSAGE,
"usage: %s [-options ...] [1 > opacity > 0, default=0.5]n"
"options:n"
" -h, --help display this messagen"
" -d, --daemon run as a daemon (background)n"
" -t, --timeout <int> timeout value for check in ms [default=100]n"
" --verbose verbose output (debug)n"
" -v, --version print version numbern", PROG_NAME);
exit(1);
}
BOOL ParseCommandLine(int argc, char** argv){
int o = -1;
int idx = 0;
struct option opts[] =
{
{"help",0,NULL,'h'},
{"daemon",0,NULL,'d'},
{"timeout",1,NULL,'t'},
{"verbose",0,NULL,1001},
{"version",0,NULL,'v'},
{0,0,0,0}
};
while ((o = getopt_long(argc, argv, "thpci:n:vm:x:12",opts,&idx)) != -1){
switch(o){
case 1001:
global.verbose = TRUE;
break;
case 't':
if(optarg){
global.timeout = atoi(optarg);
Print(PINFO, ":: timeout set to %dn", global.timeout);
}
break;
break;
case 'd':
global.daemon = TRUE;
break;
case 'v':
Print(PMESSAGE,"version: %sn",VERSION);
return FALSE;
case 'h':
default:
usage();
}
}
if(optind < argc){
global.ratio = atof(argv[optind]);
Print(PINFO, ":: ratio set to %fn", global.ratio);
}
return TRUE;
}
// entry point
int main(int argc, char** argv){
// currently shade every window, except the window coverd by the cursor
global.display = XOpenDisplay(NULL);
global.screen = XDefaultScreen(global.display);
global.root = XRootWindow(global.display,global.screen);
global.transparency = XInternAtom(global.display, OPACITY, FALSE);
global.timeout = 100;
global.verbose = FALSE;
global.daemon = FALSE;
global.ratio = 0.3;
XSetErrorHandler(x_error_handler);
if(!ParseCommandLine(argc, argv))
return 0;
if(global.daemon){
Print(PINFO, ":: running as a daemon");
daemon(0,0);
}
while(SetTransparency(OPAQUE, global.ratio * OPAQUE))
usleep(global.timeout);
return 0;
}
Offline
meh, like I said - it was written in notepad without a gcc/Xlib capable compiler...
few things:
"data" should have been "val" - it was a typo....
kill: true/false are part of C99 - in the stdbool.h header (which I forgot)
cmp: as for the VOUT macro, it was shorthand, but I seem to think I had my variable macro syntax off... it would have been more correct for me to just make an inline function...
for getting the currently focused window:
http://tronche.com/gui/x/xlib/input/XGetInputFocus.html
other than that: nice re-write... not my style of naming and things like that... (i_am_a_fan_of_this_style he he) but otherwise it's right on... good call on simply deleting the property for the "focused" window...
Offline
and the correct form for the VOUT macro would be:
#define VOUT(msg,args...) {if(verbose) printf(msg,args);}
for those of you curious about vararg macros....
Offline
actually it would be not, because your form fails if you call it with VOUT("hello world"), you need to write: #define VOUT(msg,args...) {if(verbose) printf(msg, ## args);}
btw.: i love google.
Offline
actually it would be not, because your form fails if you call it with VOUT("hello world"), you need to write: #define VOUT(msg,args...) {if(verbose) printf(msg, ## args);}
btw.: i love google.
ahh, good point - I didn't think about that...
Offline
cam was dead right - fluxbox sets different focus and unfocus transparencies out of the box
He's right about that, but "fluxbox" 0.9x doesn't use the "composite" extension that I was aware of. They use pixmap transparency fills instead, which is slower than horse hooey and you need "Esetroot" for it. However, fluxbox does have a really nice implementation for handling their "transparency" focus/unfocus, if that's what yall meant.
Ideally, any future WM using the "composite" extension should model how fluxbox 0.9x manages it. Really nice and easy to set up. When you get around to the implementation part, I would grab their related routines, stub out their "transparency" calls, make it modular for a specific WM as a plugin or otherwise, test it, and then substitute those stubs with your "composite" routines you got going now.
Offline
Oi, what's the final state on this project? I like the idea, but cmp's transparency follow's mouse function doesn't quite work for me; I'd like the focused Window to be the opaque one instead. and I don't feel like hacking C code at this time of night.
Dusty
Offline
skoal - dunno what you are talking about! start fluxbox and then run xcompmgr and you'll get all the composite transparency you need!
Offline
Oi, what's the final state on this project? I like the idea, but cmp's transparency follow's mouse function doesn't quite work for me; I'd like the focused Window to be the opaque one instead. and I don't feel like hacking C code at this time of night.
Dusty
having internet issues now... should be fairly stable... I'll see what's up tomorrow if I can
Offline
I assumed, that you can use onyl one dummy var, but you need one for every parameter.
for me it works with the changes below, but it could be that there is another bug in there, but I don't feelt like debuggin, because I don't even use a window manager, with which I would profit from this tool, anymore.
BOOL SetTransparency(uint opaque, uint translucent){
Window target = GetFocusWindow();
Window *children = NULL;
Window dummy = 0;
int num_children = 0;
int current = 0;
if(XQueryTree(global.display, global.root, &dummy, &dummy, &children, &num_children)){
Print(PINFO, ":: found %d childrenn", num_children);
for(current = 0; current < num_children; current++){
if(children[current] != target){
XChangeProperty(global.display, children[current],
global.transparency, XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &translucent, 1L);
}
}
if(children) XFree((char*)children);
}
// delete the property for the target
XDeleteProperty (global.display, target, global.transparency);
return TRUE;
}
has to be
BOOL SetTransparency(uint opaque, uint translucent){
Window target = GetFocusWindow();
Window *children = NULL;
Window dummy = 0;
Window dummy2 = 0;
int num_children = 0;
int current = 0;
if(XQueryTree(global.display, global.root, &dummy, &dummy2, &children, &num_children)){
Print(PINFO, ":: found %d childrenn", num_children);
for(current = 0; current < num_children; current++){
if(children[current] != target){
XChangeProperty(global.display, children[current],
global.transparency, XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &translucent, 1L);
}
}
if(children) XFree((char*)children);
}
// delete the property for the target
XDeleteProperty (global.display, target, global.transparency);
return TRUE;
}
Offline