How to automatically restore focus to a launched application on Windows - windows

I have developed a full-screen application that hooks into and launched by a 3rd party/client application. The problem is that the client application gets focus soon after it launches my application, with the result that although my application is full screen, and set to be on top, it does not receive keyboard input, as such the user has to click on it to bring it to focus, which makes for a poor user experience.
How can I restore focus to my application after the client acquires it?
If it matters, my application is written in C++ and has a QT UI.

Not quite the answer but the reason why my application does not have input focus. I'll let Charles Petzold explain (from Programming Windows 5ed, pg 213)
The Window that receives a particular keyboard event is the window that has input focus. The concept of input focus is closely related to the concept of the active window. The window with the input focus is either the active window or a descendant window of the active window -- that is , a child of the active window, or a child of a child of the active window, and so forth.
My Qt application is not spawned spawned by an active window and therefore does not have input focus. The solution therefore would be to parent my application to the active window. Unfortunately this is not straightforward in Qt, if at all possible.

Here is the Qt documentation:
http://doc.qt.io/qt-4.8/qwidget.html#activateWindow
http://doc.qt.io/qt-4.8/qwidget.html#raise
http://doc.qt.io/qt-4.8/qwidget.html#setFocus
Hope it helps when called after launch...

Related

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.

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.

How to wait for a Mac OS X application to fully activate

My application is a debugger and I need to frequently switch the active process between a target application and my debugger application as the user steps from one line to another within their code. I am currently using the SetFrontProcessWithOptions(…, kSetFrontProcessFrontWindowOnly) call to accomplish this.
The problem I have is that the SetFrontProcessWithOptions() call returns before the application is fully activated. SetFrontProcessWithOptions() returns when the process becomes the active process, but before its main window has been brought forward and made active. If I call SetFrontProcess again too quickly to reactivate my debugger application, Mac OS X gets confused and the layering of windows becomes muddled. Visually, the wrong window appears to be active and keyboard and menu focus is directed to what appears to be an inactive window.
I have tried using GetFrontProcess() after calling SetFrontProcessWithOptions() to poll, but GetFrontProcess() immediately returns the PSN that my code has activated with SetFrontProcessWithOptions() even though that process's windows are not yet fully activated.
Does anyone know of a way to determine when an application has become fully active with its main window ready to receive keyboard input?

OS X design decisions. Terminate the app on last window close?

Unlike Windows, GNOME and most other GUI's, OS X application programs do not all terminate if the main window (or all the windows) of that application are closed.
For example, fire up Firefox, Safari, Word, or most document based apps. Either click the red dot in the corner or type cmdW to close the window. You can see that the menu of that program is still active, and the program is still running. With OS X newbies, sometimes you will see dozens of these windowless zombies running and they wonder why their computer is getting slower.
With some document based programs, there is some sense to not terminating the application if it has no windows. For example, with Safari or Word, you can still type CmdN and get a new document window for whatever that application was designed to do: browse the web (Safari) or type a new document (Word).
Apple is mixed with their design philosophy on this. Some close on the last window closed and some do not. Third party apps are even more mixed.
There are other apps that do close when their red close button is clicked. System Preferences, Dictionary, the Mac App Store, iPhoto and Calculator do terminate when the sole or last window is closed. iCal, Address Book, iTunes, DVD Player do not terminate.
What I find particularly annoying is the applications that do not have a logical "New Document" or "Open" function yet they do not terminate when the document window is closed. Example: fire up iTunes or Address Book and terminate the main window. There sits a zombie with no window and no function other than manually selecting "Quit".
It is easy to close the application after the last window closes. Cocoa even gives you notification of that event. Just add this to your application delegate:
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
return YES;
}
My question is this: Is there any reason I should NOT terminate my application after the last window closes? Why is this so variable on OS X software? Unless the app has a "new" or "open" or some other clearly understood reason to not terminate with no window open, the failure to terminate seems like a bug to me.
Per Apple's Human Interface Guidelines (a guide for Mac developers):
In most cases, applications that are
not document-based should quit when
the main window is closed. For
Example, System Preferences quits if
the user closes the window. If an
application continues to perform some
function when the main window is
closed, however, it may be appropriate
to leave it running when the main
window is closed. For example, iTunes
continues to play when the user closes
the main window.
In general, never close a document based application when the last window closes. The user will expect to be able to open a new document without relaunching the application, and it will confuse them if they can't.
For non-document based applications, you need to consider a few things:
How long does it take for my application to open? If it takes more than a second, you should probably not quit.
Does my application need a window to be useful? If your application can do work without windows, you should not quit.
iTunes doesn't quit because, as Anne mentioned, you don't need a window to play music (question 2). It is also not based on Cocoa, so it is much more difficult to close after the last window, especially since it allows you to open windows for specific playlists so there are an indefinite number of possible windows to be open.
In my opinion, Address Book does not need to stay open. This could be a left-over design decision from older versions of OS X, or it could be that someone at Apple just thought it was better to leave it open (maybe so you can add a contact?). Both iTunes and Address Book provide access to their main interfaces through the Window menu, as well as a keyboard shortcut (Option+Command+1 for iTunes, Command+0 for Address Book).
The main iTunes window can be reopened from the 'Window' menu. Mail.app has similar behavior. I can't think of any applications that close when the last window is closed, and as such I don't think there's a good reason that your app should behave that way (in fact, i'm surprised its not in Apple's user experience guidelines, it would really bother me!).
One reason why you'd want to close e.g. the iTunes main window but keep the app open is to be able to use the app as sort of a server for third party scripts/applications. I rarely use the main iTunes interface, but instead control my music with a third party app. I also write AppleScripts for other apps that I launch instead of interacting with that app's interface.

Accept mouse clicks without activating the application?

I am working on a utility application that controls other running applications. On certain input event my application displays a window, user can pick some operation from the window, the window disappears and control returns to the previous app. My problem is that clicking in my app’s window activates my application, thus removing focus from the previous application’s window. I can re-activate the previous application when my window closes, but I’d rather keep the original application activated all the time. Is that possible?
It's quite easy to to, just make your window an instance of NSPanel (a subclass of NSWindow), and set it as non-activating in Xcode/IB (or create it programatically, with NSNonactivatingPanelMask in the style mask).
One idea would be: while your app is running, try to keept track of the active window in the system.
After you activate your app and click the command button, restore the previous active window.
This is only an idea, I don't know how to do it on mac.

Resources