Invalid content when nCurses app comes from background - c++

I have observed odd behavior with my nCurses app when putting it to background/foreground. After a couple of times my window shows invalid content. I suspect that when sending SIGSTOP/SIGCONT signals to my app I need to be handle those and refresh window, but I can't find any note about it. Does nCurses has some way of refreshing window when coming back from background? Or the reason can be different?

ncurses does have a handler for SIGTSTP, which it sets up in initscr — if it is in the default state:
SIGTSTP
This handles the stop signal, used in job control. When resuming
the process, this implementation discards pending input with
flushinput (see curs_util(3x)), and repaints the screen assuming
that it has been completely altered. It also updates the saved
terminal modes with def_shell_mode (see curs_kernel(3x))

Related

Disable window from calling SetForegroundWindow

I have a serious problem on my work machine with a third party software window stealing keyboard focus, using a winapi monitor tool i detect that whenever the windows steal focus it first call SetForegroundWindow.
While searching about, i have found the winapi LockSetForegroundWindow, wow i thought i had solved the problem, however, LockSetForegroundWindow blocks me from activating any other window.
I also found that would be possible to 'block' the window from calling SetForegroundWindow using a hook, but i have no knowledge about hooking, would like to ask if there's something else i could try.
Usually calling SetForegroundWindow() isn't bad. Since Windows XP, there is a lock that no program do this without being allowed to do this. Read the docs: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
This are the exceptions:
The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The process is being debugged.
The foreground process is not a Modern Application or the Start Screen.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
But when the third party tools uses AttachThreadInput(), it bypasses all these checks.
Just delete this "bad" software. Contact the developers.

How can I check in xlib if window exists?

I am writing c++ library in Linux using gcc.
Program opens web pages in new browser windows with
system("firefox https://www.webpage.com");
After that I use xlib to determine identifiers of each opened browser window.
Then program raises firefox windows one by one using
XRaiseWindow(display, window)
in order to make a screenshot of each window and OCR.
But if I close browser window manually and try to use
XRaiseWindow with the corresponding identifier it generates BadWindow error and terminates the program.
So how can I check in xlib if window with given window identifier exists?
From the X FAQ:
169) How do I check whether a window ID is valid?
My program has the ID of a window on a remote display.
I want to check whether the window exists before doing anything with it.
Because X is asynchronous, there isn't a guarantee that the window
would still exist between the time that you got the ID and the time you
sent an event to the window or otherwise manipulated it. What you should
do is send the event without checking, but install an error handler to
catch any BadWindow errors, which would indicate that the window no
longer exists. This scheme will work except on the [rare] occasion that
the original window has been destroyed and its ID reallocated to another
window.
You can use this scheme to make a function which checks the validity
of a window; you can make this operation almost synchronous by calling
XSync() after the request, although there is still no guarantee that the
window will exist after the result (unless the sterver is grabbed). On the
 whole, catching the error rather than pre-checking is preferable.
Long story short: You can't :P You can only damage control.

Simulate mouse click in background window

I'm trying to use SendMessage to post mouse clicks to a background window (Chrome), which works fine, but brings the window to front after every click. Is there any way to avoid that?
Before anyone says this is a duplicate question, please make sure that the other topic actually mentions not activating the target window, because I couldn't find any.
Update: aha, hiding the window does the trick, almost. It receives simulated mouse/keyboard events as intended, and doesn't show up on screen. However, I can just barely use my own mouse to navigate around the computer, and keyboard input is completely disrupted.
So my question is, how does sending messages to a window affect other applications? Since I'm not actually simulating mouse/keyboard events, shouldn't the other windows be completely oblivious to this?
Is it possibly related to the window calling SetCapture when it receives WM_LBUTTONDOWN? And how would I avoid that, other than hooking the API call (which would be very, very ugly for such a small task)?
The default handling provided by the system (via DefWindowProc) causes windows to come to the front (when clicked on) as a response to the WM_MOUSEACTIVATE message, not WM_LBUTTONDOWN.
The fact that Chrome comes to the front in response to WM_LBUTTONDOWN suggests that it's something Chrome is specifically doing, rather than default system behaviour that you might be able to prevent in some way.
The source code to Chrome is available; I suggest you have a look at it and see if it is indeed something Chrome is doing itself. If so, the only practical way you would be able to prevent it (short of compiling your own version of Chrome) is to inject code into Chrome's process and sub-class its main window procedure.

Is sending message to a non-existent window Ok?

I have a thread that send update messages to a window, I use ::SendMessage() and ::PostMessage() APIs.
I go in and out of multiple dialogs and register the dialog that I am currently in with the thread via the window handle (m_hWnd). If I exit all the way out, the main application window doesn't handle these messages. For that reason I don't register that window. At this point the thread will have the handle of an older window which now doesn't exist.
Is it okay if it sends messages to that non-existent window? I am assuming it should not do any harm but wanted to double check.
No, it is not ok to post a message to a deleted window.
There is no guarantee noone will set up shop at that address just after the previous tennant is gone.
If you use a NULL window handle, you'll post a thread message to the current threads message queue. SendMessage as far as I could google shoul be a no-op.
Might be harmless enough.
Now, we get tricky:
Under specific cicumstances it does not matter, pre-supposing well-behaved applications.
A message like WM_NULL should not make anything happen.
A window-message you globally registered in your application using RegisterWindowMessage, if you can guarantee none of your applications windows created in the meantime will choke on it.

C++ winAPI basics - switching through windows

Not very sure how to explain it in a clear way. Basicaly, the thing is that I'm looking for a method to change a current active window ( Self-produced def., hope it'll be understandable enough ) - window, where the text is directly typed right now. Whooh.
What have I allready discovered is msdn help and SetFocus() or SetActiveWindow(), but it doesn't solve my problem ( or, what is also possible, I'm just using it in a wrong way ).
Simply:
HWND Dest = GetFocus();
... //Some moving around on the 'alt-tab level' :-|
SetFocus(Dest);
Doesn't set the Dest window active again.
Please, excuse for the newbie questions, hope it won't take much time from you. Thanx!
SetFocus() does not bring a window to the top. It just sets the keyboard focus.
SetActiveWindow() on the other hand brings the specific window on top, but only if the application that calls it is also the application that owns it. ( according to the documentation).
When you say you did try SetActiveWindow() what do you mean? How did it fail? What results did it produce?
Another function you can try is SetForegroundWindow() in case you want to activate a window belonging to another application but this has its problems as you see from below (directly from the documentation):
The system restricts which processes can set the foreground window. A
process can set the foreground window only if one of the following
conditions is true:
The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
Try using the SetForegroundWindow function.
Do however note that there are limitations on this, which are explained on the MSDN page remarks sections and I've copied here.
The system restricts which processes can set the foreground window. A
process can set the foreground window only if one of the following
conditions is true:
The process is the foreground process. The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
An application cannot force a window to the foreground while the user
is working with another window. Instead, Windows flashes the taskbar
button of the window to notify the user.
What that means is that if you don't own the current foreground process (which is probably the case when the user tabs around) then you can't set a new foreground window.
There are several hacks around (google SetForegroundWindow and you will find them) but they are hacks and not a good idea - let the user decide what is in the foreground! (also as Raymond Chen explains on his blog here the hacks can often cause a program to hang)