🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.emacs.bug
Article #87401

Emacs 19.27 - response to window manager WM_DELETE_WINDOW message

#87401
From: Gary Barnes
Date: Thu, 22 Sep 1994 18:20
137 lines
5709 bytes
Emacs 19.27, unmodified, no .emacs in use
SPARCstation 2, SunOS 4.1.3
./configure sparc-sun-sunos4.1.3 --with-gcc --with-x-toolkit=athena

When the last Emacs frame receives a WM_DELETE_WINDOW message from the
window manager, Emacs simply calls kill-emacs and exits.  This is not
always appropriate and users would like to be able to customize this
action.

My solution is to add a wm-delete-window-hook which is a list of
functions to call when the last frame receives a WM_DELETE_WINDOW
message.  If the hook is nil, then kill-emacs is called.  It is up to
a non-nil hook to decide whether or not to exit.

The changes occur in src/keyboard.c.

*** keyboard.c.orig	Thu Sep 22 11:16:45 1994
--- keyboard.c	Wed Sep 21 19:15:40 1994
***************
*** 429,436 ****
--- 429,440 ----
  Lisp_Object Qmenu_bar;
  
  extern Lisp_Object Qmenu_enable;
  
+ #ifdef GEB_WM_DELETE_WINDOW
+ Lisp_Object Qwm_delete_window_hook, Vwm_delete_window_hook;
+ #endif
+ 
  Lisp_Object recursive_edit_unwind (), command_loop ();
  Lisp_Object Fthis_command_keys ();
  Lisp_Object Qextended_command_history;
  
***************
*** 2117,2124 ****
--- 2121,2184 ----
          }
  #ifdef HAVE_X11
        else if (event->kind == delete_window_event)
          {
+ #ifdef GEB_WM_DELETE_WINDOW
+             /*--We want to call a hook if we ever get DELETE_WINDOW_EVENT.
+              *  If there is no hook, *then* we call Fkill_emacs.  Otherwise
+              *  we let the hook(s) decide whether or not to exit and whether
+              *  or not to delete the frame. */
+           Lisp_Object tail, frame;
+           struct frame *f;
+ #ifdef MULTI_FRAME
+           Lisp_Object focus;
+ 
+           frame = event->frame_or_window;
+           if (XTYPE (frame) == Lisp_Window)
+             frame = WINDOW_FRAME (XWINDOW (frame));
+ 
+           focus = FRAME_FOCUS_FRAME (XFRAME (frame));
+           if (! NILP (focus))
+             frame = focus;
+ 
+           if (! EQ (frame, internal_last_event_frame)
+               && XFRAME (frame) != selected_frame)
+             obj = make_lispy_switch_frame (frame);
+           internal_last_event_frame = frame;
+ #endif /* MULTI_FRAME */
+ 
+           /* If we didn't decide to make a switch-frame event, go ahead
+              and deal with the delete. */
+ 
+           if (NILP (obj)) {
+ 
+               /* If the user destroys the only frame, Emacs should exit.
+                  Count visible frames and iconified frames.  */
+               for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+                 {
+                     frame = XCONS (tail)->car;
+                     if (XTYPE (frame) != Lisp_Frame ||
+                         EQ (frame, event->frame_or_window))
+                       continue;
+                     f = XFRAME (frame);
+                     if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
+                       break;
+                 }
+ 
+               if (! NILP (Vwm_delete_window_hook)) {
+                   if (!NILP (Vrun_hooks))
+                     call1 (Vrun_hooks, Qwm_delete_window_hook);
+               } else {
+                   if (! CONSP (tail))
+                     Fkill_emacs (Qnil);
+ 
+                   Fdelete_frame (event->frame_or_window, Qt);
+               }
+               kbd_fetch_ptr = event + 1;
+           }
+ 
+ #else /* ! GEB_WM_DELETE_WINDOW */
+ 
            Lisp_Object tail, frame;
            struct frame *f;
          
            /* If the user destroys the only frame, Emacs should exit.
***************
*** 2137,2144 ****
--- 2197,2206 ----
              Fkill_emacs (Qnil);
  
            Fdelete_frame (event->frame_or_window, Qt);
            kbd_fetch_ptr = event + 1;
+ 
+ #endif /* ! GEB_WM_DELETE_WINDOW */
          }
  #endif
        else if (event->kind == menu_bar_event)
          {
***************
*** 5960,5967 ****
--- 6022,6042 ----
    Qfunction_key = intern ("function-key");
    staticpro (&Qfunction_key);
    Qmouse_click = intern ("mouse-click");
    staticpro (&Qmouse_click);
+ #ifdef GEB_WM_DELETE_WINDOW
+   Qwm_delete_window_hook = intern ("wm-delete-window-hook");
+   staticpro (&Qwm_delete_window_hook);
+ 
+   DEFVAR_LISP ("wm-delete-window-hook", &Vwm_delete_window_hook,
+    "Hook to be run whenever a WM_DELETE_WINDOW (a.k.a. a window manager \n\
+ \"Close\" operation, often picked froma menu) is received by Emacs.\n\
+ If nil, will close the selected frame.  If this is the last frame, we then\n\
+ call kill-emacs.  If not nil, we simply execute the functions recorded on\n\
+ the hook.  It is up to them to decide what to do if this is the last frame\n\
+ and up to them to delete or not delete the selected frame.");
+   Vwm_delete_window_hook = Qnil;
+ #endif GEB_WM_DELETE_WINDOW
  
    Qmenu_enable = intern ("menu-enable");
    staticpro (&Qmenu_enable);
  
Technical Details
Message-ID: <9409221817.AA03368@igor.Rational.COM>
Path: arc1-ca.pugleaf.net!bga.com!news.sprintlink.net!howland.reston.ans.net!math.ohio-state.edu!pacific.mps.ohio-state.edu!cis.ohio-state.edu!rational.COM!geb

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: fb2f1,b3fcc6e68f8375,start
X-Google-Attributes: gidfb2f1,public
X-Google-ArrivalTime: 1994-09-22 12:44:22 PST
Path: arc1-ca.pugleaf.net!bga.com!news.sprintlink.net!howland.reston.ans.net!math.ohio-state.edu!pacific.mps.ohio-state.edu!cis.ohio-state.edu!rational.COM!geb
From: geb@rational.COM (Gary Barnes)
Newsgroups: gnu.emacs.bug
Subject: Emacs 19.27 - response to window manager WM_DELETE_WINDOW message
Date: 22 Sep 1994 14:20:06 -0400
Organization: GNUs Not Usenet
Lines: 140
Sender: daemon@cis.ohio-state.edu
Approved: bug-gnu-emacs@prep.ai.mit.edu
Distribution: gnu
Message-ID: <9409221817.AA03368@igor.Rational.COM>
Reply-To: geb@rational.com