You are not logged in.

#1 2014-01-15 23:07:49

nnoell
Member
From: Spain
Registered: 2010-08-21
Posts: 99

[SOLVED] Xlib: DestroyNotify for Transient Windows

Hi all,

I decided to write my own tiling window manager for X11 using Xlib and C language on my time off. It is looking very good at the moment, but, unfortunately, I am still quite new to X library and sometimes I don't understand what the tutorials mean sad

At the moment, my window manager works fine for all kind of windows except for 'Transient' ones. As far as I know, 'Transient Windows' are special child windows that must be at top-level (for example pop-up menus). I realised that Thunar->Help->About window is a transient one, and this can be checked with XGetTransientForHint function inside MapRequest handler, like that:

void maprequestHandler( XEvent *e ) {
    Window w = e->xmaprequest.window;
    Window parent = None;
    if( XGetTransientForHint( display, w, &parent ) ) {
        //'w' is transient and 'parent' is its parent
    }
    ...
    //map the window and add it to the stack
    ...
}

In the code above, when Thunar's About window is launched, MapRequest event handler is called (in this case maprequestHandler) and w will be Thunar's About window whereas parent will be Thunar main window. My window manager is just mapping w because parent has been mapped when Thunar was launched.

The problem starts when I want to destroy the window. As far as I know, when a window is destroyed (say by clicking on close button), DestroyNotify event is called and there, you can remove the window from the stack. My window manager recieves a DestroyNotify event for all windows except for transient ones, so, I don't know how to remove them from the stack when they are destroyed.

My killClient function (which is copied from dwm) looks like that:

void killClient() {
    Cli c = getCurrCli();
    if( !c )
        return;
    XEvent ke;
    ke.type = ClientMessage;
    ke.xclient.window = c->win;
    ke.xclient.message_type = wmatoms[WM_PROTOCOLS];
    ke.xclient.format = 32;
    ke.xclient.data.l[0] = wmatoms[WM_DELETE_WINDOW];
    ke.xclient.data.l[1] = CurrentTime;
    XSendEvent( display, c->win, False, NoEventMask, &ke );
}

Does anybody know if there is a way to 'generate' DestroyNotify events when a transient window is destroyed?

Last edited by nnoell (2014-01-16 22:19:54)

Offline

#2 2014-01-15 23:41:45

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,332
Website

Re: [SOLVED] Xlib: DestroyNotify for Transient Windows

You should not look for DestroyNotify events, instead handle UnmapNotify events.  Windows can be unmapped without being destroyed, and your window manager should not try to manage unmapped windows.  Further, anything you do in a MapRequest event is best undone in an UnmapNotify event - for proper 'symetry' for lack of a better word.

EDIT: this is true for all windows, not just transient windows.  It may be less common of an issue with top level windows as they are often (but not always) destroyed as they are unmapped (e.g. when the associated program is closing down).

Last edited by Trilby (2014-01-15 23:58:09)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3 2014-01-16 17:12:11

nnoell
Member
From: Spain
Registered: 2010-08-21
Posts: 99

Re: [SOLVED] Xlib: DestroyNotify for Transient Windows

Hi Trilby,

Actually, I have never thought of that. This sounds good and you are right, all windows (even transient ones) receive UnmapNotify event. I am going to try this when I got home. However, I have been thinking a bit about what you said and sometimes, I want to keep the window in the stack with all its configuration even if it is unmaped (for example, when I change from one desktop to another, or when I minimize it) because later, it might be mapped again using the old configuration (position, borders, etc... ).

Is this the only way of checking if a transient window is destroyed?

Thanks for your help.

Offline

#4 2014-01-16 17:38:56

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,332
Website

Re: [SOLVED] Xlib: DestroyNotify for Transient Windows

You could respond to unmap events *other* than those your window manager generates itself.  However, I'd instead encourage you to not unmap these hidden windows.  DWM, as one example, simply moves them off screen.  Though the ICCM does recommend unmapping when "iconified".

Transient windows will generate the same DestroyNotify event just like any other window - but only when they are actually destroyed.  The problem you are facing is that the client in question does not destroy the transient windows (until the whole program closes), it only unmaps them.

Potentially, you could respond to unmap events, and treat unmapped top-level windows in whatever way you wish for minimizing/iconifying, but remove any references to unmapped non-top-level windows (eg remove them from your client window data structure).

Last edited by Trilby (2014-01-16 17:40:34)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#5 2014-01-16 22:19:17

nnoell
Member
From: Spain
Registered: 2010-08-21
Posts: 99

Re: [SOLVED] Xlib: DestroyNotify for Transient Windows

Allright, that was very helpful.

Just to be on the safe side, I think I will just move the minimized/iconified windows off screen without unmapping them and remove any reference to them if they are unmaped/destroyed. That way, I will be able to know when I have to remove any reference to a window when it is "closed" smile

I really appreciate your help, I was stuck in there and now I think I can finish coding my window manager. Thanks a lot!

Offline

Board footer

Powered by FluxBB