closed window: broken pipe - Xwindows

This is a discussion on closed window: broken pipe - Xwindows ; I want to use X windows for GDL, an interpeted language. So windows can be interactively opened and the used for output. The problem is, that the user might close the window in between using the window manager. If this ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: closed window: broken pipe

  1. closed window: broken pipe

    I want to use X windows for GDL, an interpeted language.

    So windows can be interactively opened and the used for output.
    The problem is, that the user might close the window in between using
    the window manager.
    If this happens, the program terminates with 'broken pipe'.
    I tried XQueryTree, but even this terminates.
    Has anybody a hint how to check if a window is still existent
    under X windows?
    Another thing is, that even if I open several windows, if I close
    one using the window manager, all are closed.
    How to create them to be independently destroyable by the wm?
    Right now they are opened by XCreateWindow. (Actually I am using
    plplot).

    Thanks,
    marc


  2. Re: closed window: broken pipe

    Marc Schellens writes:

    > Another thing is, that even if I open several windows, if I close
    > one using the window manager, all are closed.
    > How to create them to be independently destroyable by the wm?


    Support the WM_DELETE_WINDOW protocol. Give each window a
    WM_PROTOCOLS property that lists the protocols it supports.
    Then, when the user tries to close a window with the window
    manager, it just sends a ClientMessage to the window, with
    WM_PROTOCOLS as the message type and WM_DELETE_WINDOW as data.
    When this message arrives, close the window and update your
    variables so that you won't try to use it later. You can also
    ask the user to confirm if there is unsaved data, for example.

  3. Re: closed window: broken pipe

    Kalle Olavi Niemitalo wrote:
    > Marc Schellens writes:
    >
    >>Another thing is, that even if I open several windows, if I close
    >>one using the window manager, all are closed.
    >>How to create them to be independently destroyable by the wm?

    >
    >
    > Support the WM_DELETE_WINDOW protocol. Give each window a
    > WM_PROTOCOLS property that lists the protocols it supports.


    Thanks, but how to do this. (I am using C++),

    Atom delWin = WM_DELETE_WINDOW;
    XSetWMProtocols( xwd->display, dev->window, &delWin, 1);

    does not work (WM_DELETE_WINDOW is unknown to te compiler).

    > Then, when the user tries to close a window with the window
    > manager, it just sends a ClientMessage to the window, with
    > WM_PROTOCOLS as the message type and WM_DELETE_WINDOW as data.


    How to get this message?
    Do I have to install some callback function (if so: how).

    > When this message arrives, close the window and update your
    > variables so that you won't try to use it later. You can also
    > ask the user to confirm if there is unsaved data, for example.



  4. Re: closed window: broken pipe

    Marc Schellens wrote:

    > Atom delWin = WM_DELETE_WINDOW;
    > XSetWMProtocols( xwd->display, dev->window, &delWin, 1);
    >
    > does not work (WM_DELETE_WINDOW is unknown to te compiler).


    You have to create yourself by calling XInternAtom().

    > How to get this message?
    > Do I have to install some callback function (if so: how).


    You get events of type 'ClientMessage'. Ignore these or process it in your
    event loop (which you should already have).

    Regards,
    Daniel

  5. Re: closed window: broken pipe

    >> Atom delWin = WM_DELETE_WINDOW;
    >> XSetWMProtocols( xwd->display, dev->window, &delWin, 1);
    >>
    >>does not work (WM_DELETE_WINDOW is unknown to te compiler).

    >
    >
    > You have to create yourself by calling XInternAtom().
    >
    >
    >>How to get this message?
    >>Do I have to install some callback function (if so: how).

    >
    >
    > You get events of type 'ClientMessage'. Ignore these or process it in your
    > event loop (which you should already have).
    >
    > Regards,
    > Daniel


    Thanks, I got it now going.
    Even, as I use plplot, I don't have an event loop of myself.
    So the windows get deleted the next time a graphics command is issued.
    As this is part of an interpreter, wainting for XEvents is not possible.

    Anyway, I use now something like this:

    void GDLGStream::Init()
    {
    plstream::init();

    // set_stream(); // private
    plgpls( &pls);
    XwDev *dev = (XwDev *) pls->dev;
    XwDisplay *xwd = (XwDisplay *) dev->xwd;

    wm_protocols = XInternAtom( xwd->display, "WM_PROTOCOLS", false);
    wm_delete_window = XInternAtom( xwd->display, "WM_DELETE_WINDOW", false);

    XSetWMProtocols( xwd->display, dev->window, &wm_delete_window, 1);
    }

    bool GDLGStream::Valid()
    {
    XwDev *dev = (XwDev *) pls->dev;
    XwDisplay *xwd = (XwDisplay *) dev->xwd;

    XEvent event;
    bool eventThere = XCheckTypedWindowEvent( xwd->display, dev->window,
    ClientMessage, &event);
    if( !eventThere)
    {
    return true;
    }
    if( event.xclient.message_type == wm_protocols &&
    event.xclient.data.l[0] == wm_delete_window)
    {
    return false;
    }

    XPutBackEvent( xwd->display, &event);
    return true;
    }

    The Init method is called for each window.
    But one strange thing happens:

    If Valid() is not called at least once after window creation,
    the whole stuff does not work, ie. the wm closes the window nevertheless
    and next time I try to do something I get 'broken pipe' again.

    Of course I can call Valid() once, but it astonishes me.

    Is this:
    1) expected X behaviour?
    2) A problem of the wm (KDE - kwm)?
    3) Something weired in my code?

    Thanks,
    marc














  6. Re: closed window: broken pipe

    Marc Schellens wrote:

    > XSetWMProtocols( xwd->display, dev->window, &wm_delete_window, 1);
    > }
    >
    > bool GDLGStream::Valid()
    > {
    > XwDev *dev = (XwDev *) pls->dev;
    > XwDisplay *xwd = (XwDisplay *) dev->xwd;
    >
    > XEvent event;
    > bool eventThere = XCheckTypedWindowEvent( xwd->display, dev->window,
    > ClientMessage, &event);

    [...]
    > The Init method is called for each window.
    > But one strange thing happens:
    >
    > If Valid() is not called at least once after window creation,
    > the whole stuff does not work, ie. the wm closes the window nevertheless
    > and next time I try to do something I get 'broken pipe' again.


    You have to flush the output buffer after setting the property, to send
    the request to the server. This is implicitly done by calling
    XCheckTypedEvent() in case no such event is available. If your interpreter
    doesn't flush the output buffer in any way, the property isn't
    known for this window, so the WM kills your client.

    Regards,
    Daniel

+ Reply to Thread