## 7.5 ClientMessage Handler

The EZ widget library does not handle ClientMessage events in any useful way. The default behavior is that the event dispatcher drops all ClientMessage events except one, a message with `message_type` `WM_PROTOCOLS` and content `XA_WM_DELETE_WINDOW` from your window manager. (It is sent from your window manager when you close the window.) For this message, the default action is to exit, which is not desirable for applications that uses more than of toplevel widgets. For example, in a file manager, closing a directory lister should not exist the application.

The EZ widget library includes a command for applications to hook in their own clientMessages handler.

    void EZ_SetClientMessageHandler(EZ_EventHandler handler,
                                    void *data);

This function overides the default ClientMessage handler. If set succesfully, `handler` will be invokde whenever the application receives a ClientMessage event.

Set a `NULL` ClientMessage handler reverts to the default handler.

### Example: A ClientMessage handler

Here is an example that uses a private ClientMessage handler.

When you close the main window from the menu, it pops up a dialogue asking for confirmation.

    /************************** Example ***********************/
    #include "EZ.h"

    EZ_Widget *Dialogue;         /* a dialogue       */
    Atom       WMProtocolsAtom;  /* WM_PROTOCOLS     */
    Atom       DeleteWindowAtom; /* WM_DELETE_WINDOW */

    void yesCallBack(EZ_Widget *widget, void *data)
    { EZ_Shutdown();  exit(0); }

    void noCallBack(EZ_Widget *widget, void *data)
    {
      if(widget)
        {
          EZ_Widget *toplevel = (EZ_Widget *)data;
          EZ_HideWidget(toplevel);
          EZ_ReleaseGrab();
        }
    }

    void buttonCallBack(EZ_Widget *widget, void *data)
    {
      EZ_DisplayWidget(Dialogue);
      EZ_SetGrab(Dialogue);
      EZ_SetFocusTo((EZ_Widget *)EZ_GetWidgetPtrData(Dialogue));
    }

    void clientMessageHandler(EZ_Widget *widget, void *data, int etype, XEvent *xev)
    {
      XClientMessageEvent *ev = (XClientMessageEvent *)xev;

      if(ev->message_type == WMProtocolsAtom)
        {
          Atom c = (ev->data.l)[0];
          if(c == DeleteWindowAtom)
    	{
    	  EZ_DisplayWidget(Dialogue);
    	  EZ_SetGrab(Dialogue);
    	  EZ_SetFocusTo((EZ_Widget *)EZ_GetWidgetPtrData(Dialogue));
    	}
        }
    }

    main(int argc, char **argv)
    {
      EZ_Widget *frame, *button, *buttonA;
      EZ_Widget *yes, *no;

      EZ_Initialize(argc,argv,0);
      DeleteWindowAtom = EZ_GetAtom("WM_DELETE_WINDOW");
      WMProtocolsAtom = EZ_GetAtom("WM_PROTOCOLS");

      frame   = EZ_CreateWidget(EZ_WIDGET_FRAME,          NULL,
                                0);
      button  = EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON,  frame,
                                EZ_LABEL_STRING,          "Press me",
                                EZ_CALLBACK,              buttonCallBack, NULL,
                                0);
      buttonA = EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON,  frame,
                                EZ_LABEL_STRING,          "A Button",
                                0);
      Dialogue= EZ_CreateWidget(EZ_WIDGET_FRAME,          NULL,
                                EZ_LABEL_STRING,          "Want to Quit?",
                                EZ_TRANSIENT,             True,
                                0);
      yes     = EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON,  Dialogue,
                                EZ_LABEL_STRING,          "Yes",
                                EZ_CALLBACK,              yesCallBack,NULL,
                                0);
      no      = EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON,  Dialogue,
                                EZ_LABEL_STRING,          "No",
                                EZ_CALLBACK, noCallBack,  Dialogue,
                                0);
      EZ_SetWidgetPtrData(Dialogue, no);
      EZ_SetClientMessageHandler(clientMessageHandler, NULL);
      EZ_DisplayWidget(frame);
      EZ_EventMainLoop();
    }
    /************************** Example ***********************/

HTML Documentation Maintainance:`Arturo Espinosa <arturo@nuclecu.unam.mx>`