emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Exit hooks not run at logout on w32


From: Lennart Borgman
Subject: Re: Exit hooks not run at logout on w32
Date: Thu, 29 Jun 2006 16:52:08 +0200
User-agent: Thunderbird 1.5.0.4 (Windows/20060516)

Jason Rumney wrote:
Lennart Borgman wrote:
Thanks. I did a post_msg and it works as I want it now. My concern was that data was lost on reboots and logouts (that has happened to me). Now it works like for other w32 apps:

What other w32 apps are you talking about? The Windows programming guidelines are pretty clear that the only time to interrupt shutdown is when you are performing an operation that cannot be interrupted - CD burning is given as an example. In that case you are supposed to ask the user one Yes/No question about whether they want to abort the shutdown.
I was going to say I am not aware of any other application that throws away data without asking the user at logoff. However a test showed that Thunderbird behaves that way too ;-|

I guess we are misunderstanding each other in some way. Let us see if we can clear this out. To see what I mean look Notepad for example. Edit a file without saving the changes and try to log off. You will be prompted by Notepad to save the changes before Notepad exits. And the log off process waits for Notepad to finish. I think that is good behaviour.

I am a very surprised about what the Windows programming guideline seems to say. Can you give me a link to it? There is a message named WM_QUERYENDSESSION that I thought was sent for applications to save data. (Though Emacs does not receive this. It is not clear to me why.)


As I said at the start of the thread, it would be correct for Emacs to flush its autosave buffers to disk at this point, but not to start asking all the questions that save-buffers-kill-emacs does. What if Emacs is on a secondary monitor, and the Graphics driver shuts it off when it receives the shutdown message? Emacs will be delaying shutdown waiting for a response, while the user cannot see it.
The problem with autosave is that data might be lost if the user happens to use some other tool to edit the files afterwards.

Is there some way to discover cases like the one with secondary monitors? Should there perhaps be an option telling what Emacs should do in these situations (with the choices autosave and ask the user to save changed data)?

I attach my patch as it looks now. Please try it to see how it works.
? logout-patch.diff
Index: keyboard.c
===================================================================
RCS file: /sources/emacs/emacs/src/keyboard.c,v
retrieving revision 1.854
diff -u -r1.854 keyboard.c
--- keyboard.c  5 May 2006 06:43:50 -0000       1.854
+++ keyboard.c  29 Jun 2006 06:35:22 -0000
@@ -530,6 +530,9 @@
 #endif
 Lisp_Object Qdrag_n_drop;
 Lisp_Object Qsave_session;
+#ifdef WINDOWSNT
+Lisp_Object Qw32_endsession_event;
+#endif
 #ifdef MAC_OS
 Lisp_Object Qmac_apple_event;
 #endif
@@ -4061,6 +4064,13 @@
           obj = Fcons (Qsave_session, Qnil);
          kbd_fetch_ptr = event + 1;
         }
+#ifdef WINDOWSNT
+      else if (event->kind == W32_ENDSESSION_EVENT)
+        {
+          obj = Fcons (Qw32_endsession_event, Qnil);
+         kbd_fetch_ptr = event + 1;
+        }
+#endif
       /* Just discard these, by returning nil.
         With MULTI_KBOARD, these events are used as placeholders
         when we need to randomly delete events from the queue.
@@ -5872,6 +5882,11 @@
     case SAVE_SESSION_EVENT:
       return Qsave_session;
 
+#ifdef WINDOWSNT
+    case W32_ENDSESSION_EVENT:
+      return Qw32_endsession_event;
+#endif
+
 #ifdef MAC_OS
     case MAC_APPLE_EVENT:
       {
@@ -10904,6 +10919,11 @@
   Qsave_session = intern ("save-session");
   staticpro (&Qsave_session);
 
+#ifdef WINDOWSNT
+  Qw32_endsession_event = intern ("w32-endsession-event");
+  staticpro (&Qw32_endsession_event);
+#endif
+
 #ifdef MAC_OS
   Qmac_apple_event = intern ("mac-apple-event");
   staticpro (&Qmac_apple_event);
@@ -11531,6 +11551,9 @@
    *                       "handle-select-window"); */
   initial_define_lispy_key (Vspecial_event_map, "save-session",
                            "handle-save-session");
+  /* W32 log off event */
+  initial_define_lispy_key (Vspecial_event_map, "w32-endsession-event",
+                            "save-buffers-kill-emacs");
 }
 
 /* Mark the pointers in the kboard objects.
Index: termhooks.h
===================================================================
RCS file: /sources/emacs/emacs/src/termhooks.h,v
retrieving revision 1.74
diff -u -r1.74 termhooks.h
--- termhooks.h 5 May 2006 06:45:04 -0000       1.74
+++ termhooks.h 29 Jun 2006 06:39:35 -0000
@@ -328,6 +328,10 @@
      save yourself before shutdown. */
   SAVE_SESSION_EVENT,
 
+#ifdef WINDOWSNT
+  W32_ENDSESSION_EVENT,
+#endif
+
 #ifdef MAC_OS
   /* Generated when an Apple event, a HICommand event, or a Services
      menu event is received and the corresponding handler is
Index: w32console.c
===================================================================
RCS file: /sources/emacs/emacs/src/w32console.c,v
retrieving revision 1.45
diff -u -r1.45 w32console.c
--- w32console.c        6 Feb 2006 15:23:21 -0000       1.45
+++ w32console.c        29 Jun 2006 12:35:04 -0000
@@ -41,6 +41,7 @@
 #undef HAVE_WINDOW_SYSTEM
 #include "frame.h"
 #include "w32inevt.h"
+#include "w32term.h"
 
 /* from window.c */
 extern Lisp_Object Frecenter ();
@@ -95,8 +96,31 @@
 ctrl_c_handler (unsigned long type)
 {
   /* Only ignore "interrupt" events when running interactively.  */
-  return (!noninteractive
-         && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
+/*   return (!noninteractive */
+/*       && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT)); */
+  if (!noninteractive) {
+    switch (type)
+      {
+      case CTRL_C_EVENT:
+      case CTRL_BREAK_EVENT:
+        return TRUE;
+      case CTRL_CLOSE_EVENT: // 2
+      case CTRL_LOGOFF_EVENT: // 5
+      case CTRL_SHUTDOWN_EVENT: // 6
+        /* Ending session so tell user */
+        //printf("ctrl_c_handler=%d, dwWindowsThreadid=%d\n", type, 
dwWindowsThreadId); fflush(stdout);
+        {
+          W32Msg wmsg;
+          wmsg.msg.hwnd = 0;
+          wmsg.msg.message = WM_EMACS_KILL;
+          wmsg.msg.wParam = 0;
+          wmsg.msg.lParam = 0;
+          post_msg(&wmsg);
+          return TRUE;
+        }
+      }
+  }
+  return FALSE;
 }
 
 /* If we're updating a frame, use it as the current frame
Index: w32term.c
===================================================================
RCS file: /sources/emacs/emacs/src/w32term.c,v
retrieving revision 1.246
diff -u -r1.246 w32term.c
--- w32term.c   5 Jun 2006 21:20:59 -0000       1.246
+++ w32term.c   29 Jun 2006 12:31:57 -0000
@@ -4668,6 +4668,11 @@
            }
          break;
 
+        case WM_EMACS_KILL:
+          //printf("w32_read_socket WM_EMACS_KILL\n"); fflush(stdout);
+          inev.kind = W32_ENDSESSION_EVENT;
+         break;
+
        case WM_INITMENU:
          f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]