Thread: XWindows- Close window event?

  1. #1
    Registered User
    Join Date
    Aug 2004
    Posts
    77

    XWindows- Close window event?

    I'm just doing some basic XWindows programming, but not using any wrapper libraries (GTK, motif, QT, etc). Anyway, I can't seem to get a window close request event when I use the close button by the caption (the upper right 'X' button). In Windows you get the WM_DESTROY event, but from what I can see in XWindows I don't get anything. Based on what I've read I expected the CloseNotify event but XGetNextEvent() doesn't give anything.

    My guess is that the event should come from the window manager. If I'm not mistaken its the one that provides the caption and the close button. I was under the impression that by calling XSetWMProperties() everything should be kosher between my window and the manager. Is there something else that is required to recieve some sort of close window event? Thanks for any help.

  2. #2
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    nvm...
    Last edited by Kleid-0; 01-09-2005 at 07:45 PM.

  3. #3
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    AFAIK, you obtain an atom name for the event with XInternAtom and 'attach' it with XSetWMProtocols, eg;
    Code:
    Atom wmDelete=XInternAtom(display, "WM_DELETE_WINDOW", True);
    XSetWMProtocols(display, wnd, &wmDelete, 1);
    Then in your xevent message loop you check for ClientMessage:
    Code:
    XEvent event;
    bool loop=true;
    while (loop==true)
      {
      XNextEvent(display,&event);
      switch (event.type)
        {
        case ClientMessage:
          std::cout<<"window closed"<<std::endl;
          loop=false;
          break;
        }
      }
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  4. #4
    Registered User
    Join Date
    Aug 2004
    Posts
    77
    Ok heres the full program I'm using:

    Code:
    #include<stdio.h>
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
    #include <X11/Xos.h>
    #include <X11/Xatom.h>
    
    int main (int ArgC, char **ArgV)
    {
        Display *cdisDisplay;
        int ciScreenNum;
        Screen *cscrScreenPtr;
        XWMHints *xwmhHints;
        XClassHint  *xchClass;
        XTextProperty xtpWinName, xtpIconName;
        XSizeHints *xshSize;
        char *pcIconName = "Icon Name?", *pcWinName = "Window Name?", *pcProgName = "Test App";
        XEvent xeEvent;
        Window Handle;
        
        cdisDisplay = XOpenDisplay(NULL);
        if (cdisDisplay == NULL)
        {//Failed to connect to an X Server
            printf("\nFailed to connect to the display\n");
            return 0;
        }
        else
        {
            ciScreenNum = DefaultScreen(cdisDisplay);
            cscrScreenPtr = DefaultScreenOfDisplay(cdisDisplay);
        }
        
        Handle = XCreateSimpleWindow(cdisDisplay, RootWindow(cdisDisplay, ciScreenNum), 0, 0, 200, 200, 0, BlackPixel(cdisDisplay, ciScreenNum), WhitePixel(cdisDisplay, ciScreenNum));
        
        //Allocate space for the hints
        xshSize = XAllocSizeHints();
        xwmhHints = XAllocWMHints();
        xchClass = XAllocClassHint();
        
        xshSize->flags = PPosition | PSize;
        
        XStringListToTextProperty(&pcWinName, 1, &xtpWinName);
        XStringListToTextProperty(&pcIconName, 1, &xtpIconName);
        
        xwmhHints->initial_state = NormalState;
        xwmhHints->input = True;
        xwmhHints->flags = StateHint | InputHint;
        
        xchClass->res_name = pcProgName;
        xchClass->res_class = "Base Win";
        
        XSetWMProperties(cdisDisplay, Handle, &xtpWinName, &xtpIconName, 0, NULL, xshSize, xwmhHints, xchClass);
    
        XSelectInput(cdisDisplay, Handle, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);
        XMapWindow(cdisDisplay, Handle); //Show the window
        
        while (1)
        {
            XNextEvent(cdisDisplay, &xeEvent);
            
            switch (xeEvent.type)
            {
                case  (ConfigureNotify) :
                {
                    printf("Window moved or resized!\n");
                    break;
                }
                case (ButtonPress) :
                {
                    printf("Mouse button %d pressed!\n", xeEvent.xbutton.button);
                    break;
                }
                case (DestroyNotify) :
                {
                    printf("Window killed!\n");
                }
                default :
                {
                    printf("Unknown event: %d (discarding)\n", xeEvent.type);
                    break;
                }
            }
        }
    }
    The output looks something like this, after moving the window a bit and clicking in it, then closing hte window using that top right 'X' button:

    Code:
    Unknown event: 21 (discarding)
    Window moved or resized!
    Unknown event: 19 (discarding)
    Unknown event: 12 (discarding)
    Window moved or resized!
    Window moved or resized!
    Window moved or resized!
    Mouse button 1 pressed!
    Mouse button 3 pressed!
    Mouse button 2 pressed!
    X connection to :0.0 broken (explicit kill or server shutdown).
    I am missing the XSetWMProtocols() call suggested by Ken Fitlike, I'll give that a shot and see how it does. From what I read that sounds like it could be hat I need.

  5. #5
    Registered User
    Join Date
    Aug 2004
    Posts
    77
    Thanks Ken Fitlike, adding that bit of code gets me the message.

  6. #6
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    How do you compile that code? I tried:mmm
    Code:
    kleid@Shiva:~/Programming/Laboratory$ gcc X11.c -L/usr/X11R6/lib X11.c: In function `main':
    X11.c:51: warning: passing arg 6 of `XSetWMProperties' makes integer from pointer without a cast
    /tmp/ccgYgYQ0.o(.text+0x30): In function `main':
    : undefined reference to `XOpenDisplay'
    /tmp/ccgYgYQ0.o(.text+0x112): In function `main':
    : undefined reference to `XCreateSimpleWindow'
    /tmp/ccgYgYQ0.o(.text+0x11d): In function `main':
    : undefined reference to `XAllocSizeHints'
    /tmp/ccgYgYQ0.o(.text+0x125): In function `main':
    : undefined reference to `XAllocWMHints'
    /tmp/ccgYgYQ0.o(.text+0x12d): In function `main':
    : undefined reference to `XAllocClassHint'
    /tmp/ccgYgYQ0.o(.text+0x153): In function `main':
    : undefined reference to `XStringListToTextProperty'
    /tmp/ccgYgYQ0.o(.text+0x16d): In function `main':
    : undefined reference to `XStringListToTextProperty'
    /tmp/ccgYgYQ0.o(.text+0x1e4): In function `main':
    : undefined reference to `XSetWMProperties'
    /tmp/ccgYgYQ0.o(.text+0x201): In function `main':
    : undefined reference to `XSelectInput'
    /tmp/ccgYgYQ0.o(.text+0x216): In function `main':
    : undefined reference to `XMapWindow'
    /tmp/ccgYgYQ0.o(.text+0x22b): In function `main':
    : undefined reference to `XNextEvent'
    collect2: ld returned 1 exit status
    And I also tried:
    Code:
    kleid@Shiva:~/Programming/Laboratory$ gcc X11.c -lX11
    X11.c: In function `main':
    X11.c:51: warning: passing arg 6 of `XSetWMProperties' makes integer from pointer without a cast
    /usr/bin/ld: cannot find -lX11
    collect2: ld returned 1 exit status
    What am I doing wrong :( , I know I've got the libraries.

  7. #7
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Tell the linker where to find the xlib(s) with -L path_to_xlib(s); eg. something like:
    Code:
    gcc X11.c -L /usr/X11R6/lib -lX11
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  8. #8
    UT2004 Addict Kleid-0's Avatar
    Join Date
    Dec 2004
    Posts
    656
    Thank you Ken! This is awesome! My first GUI in Linux, BWHAHAHAHA!!! ... *ahem*, I like it! :)

  9. #9
    Registered User
    Join Date
    Aug 2004
    Posts
    77
    If you try to use it for anything be sure you change line 51 from:
    Code:
    XSetWMProperties(cdisDisplay, Handle, &xtpWinName, &xtpIconName, 0, NULL, xshSize, xwmhHints, xchClass)
    To:
    Code:
    XSetWMProperties(cdisDisplay, Handle, &xtpWinName, &xtpIconName, ArgC, ArgV, xshSize, xwmhHints, xchClass)
    That functions expects to recieve the command line parameters passed to the program.

    I'll admit to being lazy when I left those out of the function call, I'm not entirely sure why the window manager needs them, but in the interest of being friendly to the manager they should be passed.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 6 measly errors
    By beene in forum Game Programming
    Replies: 11
    Last Post: 11-14-2006, 11:06 AM
  2. Button positioning
    By Lionmane in forum Windows Programming
    Replies: 76
    Last Post: 10-21-2005, 05:22 AM
  3. Window scrollbar
    By maxorator in forum Windows Programming
    Replies: 2
    Last Post: 10-07-2005, 12:31 PM
  4. My Window Class
    By Epo in forum Game Programming
    Replies: 2
    Last Post: 07-10-2005, 02:33 PM
  5. Ghost in the CD Drive
    By Natase in forum A Brief History of Cprogramming.com
    Replies: 17
    Last Post: 10-12-2001, 05:38 PM