From: raja@roma.berkeley.edu (Raja R. Kadiyala)
Subject: Re: Catching window manager's kill (Solutions)
Organization: U.C. Berkeley -- ERL
Date: Wed, 30 Dec 1992 18:32:42 GMT



My question:
>	How do I catch/stop the window mngr. from quiting my application (i.e.
>if I am running olwm the user may go up to the the title bar click to
>get the 'window' menu and select 'quit' and my app is outa there.  Likewise
>with mwm except it is 'close').

>	I want to prompt the user if he/she REALLY wants to quit.

Thanks for all the responses.  I got one to work (which is all I needed ...)
raja


Solutions:

John L. Cwikla <cwikla@wri.com>:
	Look at handling WM_SAVE_YOURSELF and WM_DELETE_WINDOW
	for regular Xt with XSetWMProtocols and
	XmInternAtom and XmAddWMProtocolCallback for Motif.

Balwalli Krishnanan <SLLKZ@CC.USU.EDU>:
	Your wm is using resources from .mwmrc (for mwm) etc. Simply 
	edit that file to suit your requirements specifically as follows..
	For .mwmrc (since i use it, i would do ..)
	...
	Menu DefaultWindowMenu
	{
	....
	"Close"	_C  Alt<Key>F4     f.exec"yourprog"
	}

  
Scott Grosch <garath@engin.umich.edu>:
Curtis Generous <generous@Sti.NASA.GOV>:
	Here is example code taken from Dan Heller's book to handle MWM
	protocols.  Hope it helps.
	Here's an mwm specific example:

/* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
 * This program is freely distributable without licensing fees and
 * is provided without guarantee or warrantee expressed or implied.
 * This program is -not- in the public domain.
 */

/* wm_delete.c -- demonstrate how to bind the Close button in the
 * window manager's system menu to the "cancel" button in a dialog.
 */
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
#include <Xm/Protocols.h>

#define YES 1
#define NO  0
int answer;

/* main() --create a pushbutton whose callback pops up a dialog box */
main(argc, argv)
char *argv[];
{
    Widget toplevel, button;
    XtAppContext app;
    void activate();

    toplevel = XtVaAppInitialize(&app, "Demos",
        NULL, 0, &argc, argv, NULL, NULL);

    button = XtCreateManagedWidget("button", xmPushButtonWidgetClass,
        toplevel, NULL, 0);
    XtAddCallback(button, XmNactivateCallback, activate, NULL);

    XtRealizeWidget(toplevel);
    XtAppMainLoop(app);
}

/* Create and popup an ErrorDialog indicating that the user may have
 * done something wrong.  The dialog contains an Ok and Cancel button,
 * but he can still choose the Close button in the titlebar.
 */
void
activate(w)
Widget w;
{
    Widget dialog, shell;
    void handle_close(), response();
    XmString t = XmStringCreateSimple("Warning: Delete All Files?");
    Atom WM_DELETE_WINDOW;
    Arg args[2];

    /* Make sure the VendorShell associated with the dialog does not
     * react to the user's selection of the Close system menu item.
     */
    XtSetArg(args[0], XmNmessageString, t);
    XtSetArg(args[1], XmNdeleteResponse, XmDO_NOTHING);
    dialog = XmCreateWarningDialog(w, "notice", args, 2);
    XmStringFree(t);

    /* add callback routines for ok and cancel -- desensitize help */
    XtAddCallback(dialog, XmNokCallback, response, NULL);
    XtAddCallback(dialog, XmNcancelCallback, response, NULL);
    XtSetSensitive(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON), False);

    XtManageChild(dialog);

    /* Add a callback for the WM_DELETE_WINDOW protocol */
    shell = XtParent(dialog);
    WM_DELETE_WINDOW = XmInternAtom(XtDisplay(w), "WM_DELETE_WINDOW", False);
    XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, response, dialog);
}

/* callback for the Ok and Cancel buttons in the dialog -- may also be
 * called from the WM_DELETE_WINDOW protocol message sent by the wm.
 */
void
response(widget, client_data, cbs)
Widget widget;
XtPointer client_data;
XmAnyCallbackStruct *cbs;
{
    Widget dialog;

    if (cbs->reason == XmCR_OK) {
        answer = YES;
        puts("Yes.");
    } else {
        answer = NO;
        puts("No.");
    }
    /* test that "reason" is not the cancel button and not the ok button.
     * It's value is XmCR_PROTOCOLS (6666), but we can't check for that
     * because OSF didn't make that value public.
     */
    if (cbs->reason != XmCR_CANCEL && cbs->reason != XmCR_OK)
        /* we passed the dialog as client data for the protocol callback */
        dialog = (Widget)client_data;
    else
        dialog = widget;

    XtDestroyWidget(dialog);
}


Doug Clinton <dec@alex.com>:
	You need to tell the window manager that you are interested in the
	WM_PROTOCOL message WM_DELETE_WINDOW. You can do this in Motif using
	the XmAddProtocolCallback function and related functions. See also the
	VendorShell widget.


Michael E. Dupree <zmed0b@trc.amoco.com>:
	Atom wm_delete_window;
	...
	...
	...
	
	wm_delete_window=XmInternAtom(XtDisplay(toplevel),
						"WM_DELETE_WINDOW",False);
	XmAddWMProtocols(toplevel,&wm_delete_window,1);
	XmAddWMProtocolCallback(toplevel,wm_delete_window,
					exit_dialog, (XtPointer) app_context);

	This will trap for the Delete Window signal and call the exit_dialog
	callback when this signal is received.

--
Raja R. Kadiyala			UC Berkeley Robotics Lab
Mail is forwarded to:			raja@robotics.berkeley.edu
Office  333-5D Cory Hall		Phone: (510) 643-5798
Lab     330    Cory Hall		Phone: (510) 642-3248 or 2-7824