How to prevent reparented window blocking X session? - x11

I reparent an external window into Qt application (XReparentWindow, XMapRaised, XMoveResizeWindow). It works, but when I click to that reparented window the system locks (no mouse or keyboard events), expect of may be some input inside the reparented window or may be my application.
Trying to embed, for example, gedit and clicking into it leads to keyboard events only in gedit (and even global Awesome's hotkeys disabled) and no mouse clicks anywhere (unless I close embedded gedit using Ctrl+Q).
The same if using QX11EmbedContainer. Even if do setEnabled(false) to it.
Why it locks up? How to prevent this lockup or how to disable input processing for some X window?

Reparenting a window into one own's application is covered by the XEmbed specification. If you read that spec, you'll see, that some additional work is to be done to make this work:
http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html

Related

Windows-10-IOT QT-C++/QML App Fullscreen Gui Frozen when monitor turns back on

ISSUE:
On a touch panel with no keyboard, my QT C++/QML app running on Windows 10 IOT has the fullscreen GUI "frozen", when the monitor turns on (after the user has triggered the touchscreen), after it has timed-out earlier and turned off due to power settings. Mouse cursor still updates.
The QML GUI has "flags: Qt.FramelessWindowHint | Qt.Window"; I do not want to add "Qt.WindowStaysOnTopHint" as it will block the control panel window when it is open from the app. The program is verified to be still running, only the GUI has frozen from the point in time when the screen turned off.
TEMPORARY RESOLUTION:
The only way to "unfreeze" the fullscreen GUI is to connect a keyboard & press the Windows key to show-hide the start menu, or do it programmatically with a manual QML button placed at a known position or on detection of monitor WM_POWERBROADCAST messages.
When the app is not fullscreen, the freezing doesn't seem to be happening.
Is this due to some missing WM_MESSAGES (e.g. WM_PAINT, WM_ACTIVATE, etc) sent by the OS to the app when it is fullscreen, or when the start menu button is pressed?
Can the app-fullscreen-freezing on monitor-turn-back-on be rectified by the app programmatically sending a sequence of WM_MESSAGES to itself, but not the Win button keypress (as the normal user is not supposed to access the OS or see anything related to the OS when the app is running)?
I tried using winAPI SetForegroundWindow() function...?
:-( Fast forward a few days...
With further testing, it seems that using SetForegroundWindow() alone is not consistent/reliable. Sometimes it works, sometimes it doesn't.
The most reliable that works 99.999% of the time is still the VK_LWIN keypress sent by the app. But, as mentioned before, the app user is not supposed to see the start-menu appearing then disappearing. Best if the behavior of the VK_LWIN keypress could be duplicated to the app without seeing the start-menu...

Win32: how does the OS decide to re-assign focus on window close?

When a focused window is closed, Windows will typically set focus to a different window when possible. I'm trying to figure out what exactly causes this to happen, and in what scenarios does this not occur.
I'm noticing that when some windows are closed, they do not cause the OS to set focus to a new window (eg. Discord, Slack). Discord and Slack are both hidden instead of destroyed on close, but then there are also other windows that when hidden will still cause the OS to set focus to a different window. One such example is with a fresh WPF app and changing the window's Visibility to Collapsed - this causes the window to be hidden, not destroyed, and yet the OS reassigns focus to another window.
What causes some windows when hidden to reassign focus (eg. WPF collapse)? As opposed to applications like Discord/Slack, which are hidden, yet do not reassign OS focus.
It's a multi-step dance of message exchanges, and I no longer have all the details cached in my head. So, generally speaking ...
There's a distinction between activating a window and setting the focus to a window. Windows can get activated in various ways, including a mouse click (either in the client or non-client areas, a keyboard operation, a window being created by a process that currently has "the foreground love", etc.)
A window that's activated can (in effect) accept the focus, reject the focus, or direct the focus to another window (such as a child window like an edit control or button).
A window that doesn't make the effort to direct the focus explicitly when its activated will (likely) end up with the focus by default. That's mostly an artifact of how DefWindowProc handles the relevant messages. But if it's using the dialog manager, then the dialog manager will (if I recall correctly) set the focus to one of the child windows that has the WS_TABSTOP window style.
Imagine a simple text editor application that has a top-level window and one child window that fill the top-level window's client area and hosts the actual editor functionality. In normal behavior, the child window would have the focus whenever the application is in the foreground. But if the top-level window is activated (for something other than a mouse click in the child window's client area), and the top-level window fails to redirect the focus to its child, then it may appear as though nothing has the focus because the window that does have the focus doesn't respond to most kinds of keyboard input.
Key messages involved include: WM_ACTIVATEAPP, WM_NCACTIVATE, WM_ACTIVATE, WM_MOUSEACTIVATE, WM_SETFOCUS, and WM_KILLFOCUS.
Edited to emphasize
what causes the OS to re-assign focus from a window?
In most cases, the OS does not assign focus. It activates and deactivates windows, and the affected applications respond to those events by setting the focus. Applications have a lot of flexibility in how to respond. So if there's an anomaly in where the focus is, it may be more of a question about the behavior of individual applications than about Windows.
It's also possible for a window to have focus but for it to seem as if no window has focus. One case is where the top-level window has focus but doesn't react to the keyboard itself because focus is normally supposed to be assigned to one if its child windows. It's also possible for a hidden window (at least a hidden child window) to have focus if it's not disabled.
Win32's DefWindowProc and dialog-specific APIs, MFC, WPF, and other frameworks generally provide "standard" behavior for handling focus and activation in common cases. But there's a lot of nuance, and there are inherently some differences. For example, WPF applications (if I recall correctly) use windowless child controls, so the traditional behaviors have to be implemented by the framework.

Closing window rather than withdraw TCL

I am using a graphic user interface builder for Tcl/Tk called "GUI Builder (Komodo Pro)". I have built three different windows that will each be opened after the respective button is clicked. I have managed to get the windows to open and "withdraw", but the process remains open in the background. If the user opens enough windows the program will crash due to the large number of windows.
My question is how can I get the window to fully close, instead of withdraw, thereby save some of the computers memory and process power?
When you click on the window manager close button for a window (which varies a bit in style, but is often a red “X”) Tk ends up receiving a WM_DELETE_WINDOW protocol event (non-X11 platforms are translated to this inside the lower levels of Tk). Tk then responds to this for that window in “the appropriate way”.
By default, windows are destroyed when a WM_DELETE_WINDOW is sent to them; this is the right thing to do in the simple case. You can also explicitly enable this by doing:
wm protocol $toplevel WM_DELETE_WINDOW [list destroy $toplevel]
You wouldn't normally bother with that; the default (which is what happens when you've got an empty handler) has the same effect.
Alternatively, you can make the window withdraw (wm withdraw $toplevel instead of destroy $toplevel) or iconify (wm iconify $toplevel) or even pop up a dialog to check whether the user is really sure about that.
Tk-enabled applications normally exit once they enter the main event loop with all toplevel windows are closed. In the simplest case (only one Tcl interpreter with Tk loaded) this is the same as saying that the application stops once the . window is destroyed. However, I'm not entirely sure if this is true if you run the Tk application in tclsh by doing package require Tk (there's magic in the code to integrate Tcl and Tk). The best way to find out whether things go away right is to test for yourself; it should only take a moment…

How to prevent wxWidgets window from blinking in the taskbar when created?

If my wxWidgets application creates a new window while the application does not have focus, its taskbar icon blinks yellow until I switch to it, as shown here:
This is annoying. How can I prevent this from happening?
EDIT: The original version of this question suggested the blinking was happening during startup. After further investigation, this is not occurring right at application startup; rather, it occurs if I create an additional window while the application does not have focus.
To give a bit more background: my application is a sort of server, that opens windows in response to network events. If I boot up the application, then switch focus to something else and a network event comes in while the focus is elsewhere, my application will open a new window in the background (not grabbing focus) and this blinking will occur.
The windows are wxFrames; the application constructs them and their child widgets, then calls Show(true) on the frame.
Also, I've attempted to set a breakpoint on the FlashWindow Win32 API function, hoping to trap wherever in WX it's getting called, but haven't been able to make that work.
Maybe the following would work:
wxTopLevelWindow::ShowWithoutActivating ( )
http://docs.wxwidgets.org/trunk/classwx_top_level_window.html#a03e526f505716568318d601318527bd0
Yes. If you create a new top level window while the app does not have focus, then the task bar icon will flash. This is the intended behaviour of the windows operating system.

Is it possible to create a sub window which will not deactivate the parent?

Normally when creating a sub window (WS_POPUP), the child window will become activate and the parent will become deactivated. However, with menus, both remain active. At least I am assuming the menu is active, it at least has focus.
Example: Click on the file menu in notepad, the menu appears, yet the notepad window still looks active.
Is it possible to mirror this behavior with either a window style or responding to a particular message?
Thanks
Another example: Combo boxes seem to show a subwindow, yet do not deactivate the window. And you can click on that subwindow, while still maintaining an activate main window. Any ideas on how to grab the class /style of that window?
The list dropdown in a combobox is a bit of a hack, it is both a popup and a child window, I can't recommend that approach (Undocumented style combination, and IIRC, it is a bit buggy to do this with a "normal" floating window/toolbar)
This leaves you with two options:
WS_EX_NOACTIVATE (Main window will stay active, floating window is not active)
Handle activate messages (Both windows will look active)
I am surprised that creating a new popup window activates it. Normally you'd need to call SetActiveWindow. However check out WM_ACTIVATE and WM_NCACTIVATE on how to stop the window becoming deactivated.
A fact that a lot of people miss is that windows does not have a separate window manager component :- most of the window management duties are performed by each window - usually in DefWindowProc.
Most window positioning and activation / de-activation is done - ultimately - via a call to SetWindowPos - which always sends a WM_WINDOWPOSCHANGING message allowing the window to have a final say on what happens.
DefWindowProc also activate its own window in response to mouse clicks and so on.
The result of all this is, it is quite possible to create windows that never accept activation - it does require an extensive understanding of what messages and situations might have led to an activation.
Ultimately I can say that it is VERY handy to have a debugging setup configured for remote debugging - so that you can interact with your debugger without effecting the activation state of the system - and hence drop a breakpoint into the window in questions WM_ACTIVATE handler and simply debug any situation leading to an unwanted activation.
If You want to handle keyboard focus as well, it might be trickier - normally focus is given to an activated window - but again its usually the DefWindowProc responsible for assigning both. I just see it dangerous as having one window, still obviously activated, and another with focus. This will confuse any assistive software greatly.
I'd be tempted to perform a message loop level message hook - Similar to IsDialogMessage - to filter keystrokes intended for the popup window.
If you create your popup window with WS_EX_NOACTIVATE it will not be activated by user input (You could still activate it programatically) and therefore your main application window will still remain active.

Resources