Re: Application launch detection



> I think hacking this into XMapWindow is simply wrong:
> 
>  - Functions like MapWindow are wrappers around the X wire
>    protocol. When I say, XMapWindow(), I mean "map the window on the
>    server".  Xlib is not there to make interpretations of what I mean
>    and send extra events around or set extra properties.

We want to stop the feedback indicator when "something shows up on the
screen". As far as i know, this corresponds fairly well with the call to
XMapWindow(). We don't want to change the semantics of XMapWindow(), only
add a hook. I agree that we want to minimize extra events and properties,
but some technique is required. 

>  - XMapWindow has no idea whether the window it is mapping is
>    an immediate child of the root window, so I don't see how to
>    implement the modified XMapWindow without major slowdowns
>    or major changes to XLib.

It's sufficient to send the signal (or whatever) on the first
XMapWindow. In my demo code (see
http://www.lysator.liu.se/~astrand/projects/xalf/monitor.tar.gz), this is
done:


extern int                                                                                               
XMapWindow (Display* display, Window w)                                                                  
{                                                                                                        
    int i;                                                                                               
           
    /* Original function */                                                                                              
    i = ((XMType)pfXMapWindow)(display, w);                                                              
                                                                                                         
    send_signal(display, w);                                                                             
                                                                                                         
    return i;                                                                                            
}          


void                                                                                                     
send_signal(Display *dpy, Window w)                                                                      
{                                                                                                        
    const char *id_string;                                                                               
                                                                                                         
    id_string = getenv (ID_PROPERTY_NAME);                                                               
    if (id_string && *id_string) {                                                                       
        Atom xa_launch_id = XInternAtom(dpy, ID_PROPERTY_NAME, False);                                   
        XClientMessageEvent xev;                                                                         
                                                                                                         
        xev.type = ClientMessage;                                                                        
        xev.window = w;                                                                                  
        xev.message_type = xa_launch_id;                                                                 
        xev.format = 8;                                                                                  
        strncpy(xev.data.b, id_string, 20);                                                              
                                                                                                         
        XSendEvent (dpy, DefaultRootWindow(dpy), False,
		SubstructureNotifyMask, (XEvent *) &xev);        
                                                                                                         
        putenv (ID_PROPERTY_NAME "=");                                                                   
    }                                                                                                    
} 


All subsequent calls to XMapWindow will have the penalty of doing:

id_string = getenv (ID_PROPERTY_NAME); if (id_string && *id_string) { }

but I think we can live with that. Afterall, an normal app just uses ten
or so calls to XMapWindow, it is not that much. 


>  - Changing what XMapWindow to set properties as well may cause
>    unexpected side effects such as PropertyNotify events that
>    could potentially break legacy apps.

Maybe, if we choose an property approach. My demo code above does not
suffer from this. The event showing up on the root window could be sent by
any application. 

>  - The first window being mapped may correspond very badly
>    to the idea of the app starting up.

Wrong. I'm using this in Xalf, and it works great. 

> Now, if you wanted to change X[mb]SetWMProperties to handle setting
> the PID, that might make sense. After all, it is very closely related
> to what it is doing already. It might even be able to set the
> LAUNCH_ID property, if that is what we decide to use, though I believe
> that would interfere with toolkits doing more sophisticated things.

But not all applications call X[mb]SetWMProperties, or? Then this won't
work very well. 

> Basically, don't try to put policy into Xlib, and especially not into
> functions that are defined as wrappers around the X protocol - that is
> the domain of the toolkit. If you want to hack X code, extend Xt, but
> XMapWindow should not be changed.

The problem with extending Xt, GTK or QT is that there will always be
thousand and thousands of applications and toolkits without this
extension. Eg, this feedback mechanism will only work with perhaps 90% of
the applications. This means that the desktop environment much decide
if to use feedback or not - not an easy task. Including some flag in the
.desktop file is probably the only way to do it. Not a clean solution. 


-- 
/Peter Astrand <astrand lysator liu se>







[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]