randombio.com | computer notes
Saturday, April 01 2023

Solved: Keyboard freezing in Linux when using multiple files in non-tabbed mode

Bug in new Linux libraries causes a problem with old software

Version

Nedit 5.7 in Debian 11.5 Linux with supplied Motif. The Nedit binary has 29 linked libraries including libbrotlidec.so.1, libmd.so.0, and libbrotlicommon.so.1. Older versions without these three libraries do not show the problem. Compiling a 'static' version of Nedit doesn't help. (It also does not really create a static version.)

How to reproduce

1. Configure the editor not to open each file in a new tab.
2. Load two or more files into the editor.
3. Close one of the files.
4. The keyboard is frozen and it is impossible to enter text or move the cursor with the arrow keys.

The bug doesn't happen if Nedit is set to open files in tabbed mode. If a working version of Nedit from an older machine is installed, Nedit automatically uses the three new libraries and shows the bug. This means the bug is in the new libraries.

Solution

The problem occurs in the function CloseWindow() in window.c at the line XtDestroyWidget(window->shell); One change that helps is at the point after it says

/* if this is the last window, or must be kept alive temporarily because
it's running the macro calling us, don't close it, make it Untitled */
if (keepWindow || (WindowList == window && window->next == NULL)) {

move the 'if' statement shown above to the end of the statement block. Move the 'return' line so it's after the 'if' statement. The end of the block should look like this:

if (keepWindow || (WindowList == window && window->next == NULL))
return;

The goal is to execute all the statements in the block regardless of whether it's the last window or not. Then recompile.

This isn't a complete fix. When you load three or more files, the cursor still stops working when you close one—but only sometimes. This is a classic sign of an uninitialized variable somewhere.

Replacing the XtDestroyWidget line in CloseWindow with these two lines

XtUnmap(window->shell);
return;

solves the problem. It's not an ideal solution because it causes a memory leak, but when CloseWindow is called the file is already saved, so the leak is small.


On the Internet, no one can tell whether you're a dolphin or a porpoise
apr 01 2023

back

to top