Catching window system events (MS Windows)

Catching window system events (MS Windows)

Post by Paul Moo » Fri, 04 Jul 2003 22:09:08



I'm trying to set up XEmacs to make it hard for me to "accidentally"
shut down XEmacs. I have done much of what I want by adding an
exit-emacs hook, which asks me if I really mean to shut down, and
raises an error if I say "no".

But I'd like to go a little further. I can rebind C-x C-c to make that
key combination not exit Emacs. And I can rebind the menu entry and
M-f4 keystroke to make the menu do what I want.

But I can't see an obvious way of getting at the "system" close
methods - the close icon at the top right, and the system menu (top
left) "Close" item. These don't actually exit XEmacs - they close the
frame, and only exit XEmacs if the *last* frame is closed. I'd like to
close the frame, but if it's the last frame, minimise it - for now
just using (iconify-frame) but ideally to the system tray (but I need
to write a helper application to do that).

I can't see a way of hooking that "system close" functionality. I've
searched the "obvious" places - key bindings, menu bindings, hooks.
The only one even close is to use the exit-emacs-hook, but then (a) I
have to raise an error to stop the exit occurring, which is ugly, and
(b) it doesn't distinguish between the "system close" and any other
type (unless I can get this somehow from the current event, but I
don't know how...)

Has anyone got any suggestions?

Paul.

PS Actually, having a variable mswindows-close-to-systray or
something, which if true made XEmacs respond to the "close" icon on
the last frame by minimising to the system tray (like a number of
other programs have) would be nice, but it's very MS-specific...

 
 
 

Catching window system events (MS Windows)

Post by Stephen J. Turnbul » Sat, 05 Jul 2003 01:44:54


    Paul> I can't see a way of hooking that "system close"
    Paul> functionality. I've searched the "obvious" places - key
    Paul> bindings, menu bindings, hooks.

I don't think you can.  XEmacs (I'm guessing---I don't do Windows)
gets this information as a WM_CLOSE message.  All it does is to
enqueue an eval event for (delete-frame FRAME t).

You could try this patch (against 21.5; it won't apply to 21.4 due to
an extra linebreak, but what you need to do is obvious):

Index: src/event-msw.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/event-msw.c,v
retrieving revision 1.94
diff -u -r1.94 event-msw.c
--- src/event-msw.c     9 Mar 2003 02:27:42 -0000       1.94

     case WM_CLOSE:
       fobj = mswindows_find_frame (hwnd);
       mswindows_enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj,
-                                                            Qt));
+                                                            Qnil));
       break;

     case WM_KEYUP:

This will signal an error.  I'm not sure where you can catch that
error, but you won't exit XEmacs.  The obvious place to do surgery in
in delete_frame_internal in frame.c, near the comment about deleting
the last frame (search for "delete-frame" in that file).

    Paul> PS Actually, having a variable mswindows-close-to-systray or
    Paul> something, which if true made XEmacs respond to the "close"
    Paul> icon on the last frame by minimising to the system tray
    Paul> (like a number of other programs have) would be nice, but
    Paul> it's very MS-specific...

Not really.  It would make sense to dock the app for window managers
that have docks, and iconify otherwise.  But ...

You'll have to write that one yourself.  I don't do Windows.  :-)

--
Institute of Policy and Planning Sciences     http://turnbull.sk.tsukuba.ac.jp
University of Tsukuba                    Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
               Ask not how you can "do" free software business;
              ask what your business can "do for" free software.

 
 
 

Catching window system events (MS Windows)

Post by Paul Moor » Sat, 05 Jul 2003 03:25:07



Quote:> You could try this patch (against 21.5; it won't apply to 21.4 due to
> an extra linebreak, but what you need to do is obvious):

[...]

Quote:> This will signal an error.  I'm not sure where you can catch that
> error, but you won't exit XEmacs.  The obvious place to do surgery in
> in delete_frame_internal in frame.c, near the comment about deleting
> the last frame (search for "delete-frame" in that file).

Interesting. Thanks for the pointers for places to look. I don't
really want to fiddle with patching the sources, unless I can do so in
a way that is more generally useful, but I've got an idea where to
look now, which is over half the battle :-)

Quote:>     Paul> (like a number of other programs have) would be nice, but
>     Paul> it's very MS-specific...

> Not really.  It would make sense to dock the app for window managers
> that have docks, and iconify otherwise.  But ...

Sounds like lots of OS/window-manager specific code. Probably not a
good idea. I'll see if I can think of a more generic answer...

Quote:> You'll have to write that one yourself.  I don't do Windows.  :-)

You're doing good enough for me :-) Thanks for all your help!

Paul.
--
This signature intentionally left blank

 
 
 

Catching window system events (MS Windows)

Post by Stephen J. Turnbul » Sat, 05 Jul 2003 13:29:40


    >> Not really.  It would make sense to dock the app for window managers
    >> that have docks, and iconify otherwise.  But ...

    Paul> Sounds like lots of OS/window-manager specific
    Paul> code. Probably not a good idea. I'll see if I can think of a
    Paul> more generic answer...

Here's The Canonical XEmacs Way[tm].  :-)

Does the Windows system tray adequately correspond to the docks that
are used by (eg) WindowMaker on X or Aqua (is that the right
component?) on Mac OS X?  If so, choose a name for the generic
functionality, I would say "dock" or maybe "tray" for brevity.  Make
sure it is documented that this function applies to "docks" on systems
that have docks and to "system trays" on systems that have trays, or
whatever.  "Dock" is probably more naturally "verbified" (`dock-frame'
vs `tray-frame', to correspond to similar APIs like `delete-frame' and
`iconify-frame').  Later we might want to create system-specific
aliases so apropos searches work, but that's not an issue now.  This
function would be bound to a Lisp function symbol, and would simply
dispatch to a device-specific implementation.  It would live in
frame.c.

Whether that function would be called or not would be decided in Lisp
code.  It doesn't need any logic about is this a system close event,
etc.

Then what would happen is that an additional slot would be created in
the generic frame structure (defined in frame.h or frame-impl.h) to
hold the device-specific function.  This function's implementation
would live in frame-msw.c.  There's some preprocessor infrastructure
(to simulate an OO language in C) that needs to be added to frame.h.
Easy pie, once you get used to it.  :-)

You would only have to implement the method for Windows, which would
presumably be very straight forward.  On X you'd probably have to
figure out which window manager and dispatch on that basis, but it's
not your problem as a MS Windows developer.

The two considerations are (1) if it's not implemented so that it's
generalizable, it will probably get vetoed, and (2) since you aren't
specifically interested in non-Windows window managers, you'll
probably get the design wrong for them---and that will turn around and
force you to adjust your implementation to the New! Improved!
Portable! generic scheme.  Usually that's not terribly painful, though.

--
Institute of Policy and Planning Sciences     http://turnbull.sk.tsukuba.ac.jp
University of Tsukuba                    Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
               Ask not how you can "do" free software business;
              ask what your business can "do for" free software.

 
 
 

Catching window system events (MS Windows)

Post by Paul Moo » Sat, 05 Jul 2003 19:37:02



Quote:> You could try this patch (against 21.5; it won't apply to 21.4 due to
> an extra linebreak, but what you need to do is obvious):

That gave me the hint I needed. The event is queued as a
misc-user-event, so I can check when XEmacs is in the process of dying
whether the cause was a misc-user-event, and if so assume that it's a
WM_CLOSE (vaguely risky, but not massively...) So all I need is:

  (defun my-confirm-kill-emacs (prompt)
    (if (misc-user-event-p last-command-event)
        (progn (iconify-frame) nil)
      (yes-or-no-p prompt)))

  (setq confirm-kill-emacs #'my-confirm-kill-emacs)

This still does a save-all before iconifying the frame, but that's a
minor annoyance.

Brilliant. That gets me a good way to what I want. In the medium term,
I'll ponder your other message about a generic docking method, and try
to implement something. It doesn't seem like it'll be too hard
(although Windows is annoyingly unhelpful in supporting system tray
icons, so that may be fiddly...)

Once again, thanks for all your help.

Paul.

 
 
 

1. Using Emacs 19.29 without poping out a window under X Windows System?

  Hsiu-Chin> I just installed Emacs 19.29 at SUN 4.1.4, and found it
  Hsiu-Chin> pops out a new window under X Windows.  How can I use
  Hsiu-Chin> Emacs 19.29 under X Windows System without poping out a
  Hsiu-Chin> new window?

(1) Type `emacs -nw' to start Emacs.

(2) Unset the DISPLAY environment variable.  If this variable doesn't
    exist, Emacs thinks there is no X and uses the xterm instead.

hth,
        \kai{}
--
Life is hard and then you die.

2. Cabletron New SmartSwitch Router???

3. (MS Windows) Getting the HWND for a frame

4. SQL Net and Oracle CDE

5. desktop.el broken after upgrade (ms-windows)

6. MICRO-33 Advance Program

7. MS windows Xemacs: Meta (alt) shortcuts open menu

8. ESP confusion.

9. Cool Trick Part 3: Doing It On MS Windows : Switching Ctrl & Caps Lock Key Mappings

10. How to use cc-mode, psgml, etc. from MS Windows versions?

11. XEmacs-FAQ: [6/7] 6 XEmacs on MS Windows

12. using SUPER and HYPER keys in ms-windows

13. about speedbar for xemacs on MS-windows