Is closing the window of a X client application process necessarily followed by terminating the process

processwindowx11

When the window of a X client application is closed, is that necessarily followed by terminating the application process (only attempt to terminate, regardless of success of failure)?

When that is followed by terminating the application process, how is the process notified to terminate? By some signal whose default action is to terminate the process, and if yes, what sends the signal?

Thanks.

Best Answer

tl;dr; the X11 protocol has no idea of processes, signals or any kind of IPC; both the server and any of its clients may be on different machines and operating system, which may simply have no concept of processes at all (at the time the X11 protocol was designed, Lisp machines were still a thing). The X11 itself protocol may run on top of unix sockets, tcp/ip or be tunneled through ssh, etc.

There are 3 ways to "close" an X11 window:

  1. Send a ClientMessage event with the WM_DELETE_WINDOW atom to that window. The application that created that window may act on it (eg. xclock, xeyes will just exit; other may close that window and continue running) or may ignore it. This is what typically happens when you press the X button or press some "standard" key combo like Alt-F4.

  2. Forcefully destroy that window with XDestroyWindow. The app may not expect it and may ignore any DestroyNotify event, and still try to do operations on that window as if it were still existing, which will cause it to receive an XErrorEvent with its code set to BadWindow. The default error handler from Xlib (set with XSetErrorHandler) will print an error message and do a clean exit(3) in that case.

  3. Call XKillClient on that window, which will forcefully close the client which has created it (instead of a window you can use any X11 resource, eg. the XID of a pixmap). This is what xkill(1) does [1]. This has nothing to do with kill(2) or kill(1) and does not send any signal to any process. Unless the client has taken special measures (see XSetCloseDownMode(3)) all the resources it has created (windows, pixmaps, graphic contexts) will be destroyed. Again, the default Xlib io error handler (set with XSetIOErrorHandler) will print an error message and do a clean exit(3) in this case, too. The difference from pt. 2. is that the handler set with XSetIOErrorHandler cannot return.

Some apps quite annoyingly treat 2. and 3. as a "crash" (eg. firefox which will show its infamous "Well this is embarasssing" message on the next start, unless browser.sessionstore.resume_from_crash is set to false).

Also, an app has no way to know if it was kicked out the server with XKillClient or if the server itself has closed unexpectedly or crashed.

Another thing that it's worth rehashing is that the X11 protocol is cooperative by design; there are no barriers and checks between X11 clients; any client can kick any other client out with XKillClient, destroy or resize its windows, grab the keyboard or mouse all to itself, set the override redirect flag to get the window manager out of the way, etc.

[1] unless you're using a reparenting wm, you should use xkill -frame for it to work.

Related Question