How can I prevent other windows within my application from receiving focus? I want to bring a loading window to the front and let it do its thing, but I don't want the user to be able to interact with the other windows in the app.
I could simply hide the other windows in the app, but that feels kind of jarring for users to have their windows just suddenly disappear. At the same time, I can't let the user continue interacting with the other windows during a load since the load will be updating data on every window (synchronization problems would occur). I can add additional locking mechanisms, but I'd rather not if it is as simple as forcing a single window to stay on top and remain in focus.
Thanks!
Look into modal windows.
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/WinPanel/Concepts/UsingModalWindows.html
You can make a whole window or panel run in application-modal fashion,
using the application’s normal event loop machinery but restricting
input to the modal window or panel. Modal operation is useful for
windows and panels that require the user’s attention before an action
can proceed. Examples include error messages and warnings, as well as
operations that require input, such as open dialogs, or dialogs that
apply to multiple windows.
Related
I have a background process running on the user’s macOS machine. Its job is to detect whenever any app is launched on the machine. Currently, I am detecting the NSNotificationCenter’s NSWorkspaceDidLaunchApplicationNotification event. This works perfectly for detecting when an app is freshly launched (i.e. the app had no instance already running at that time).
But, on macOS, if we click the red cross button at the top-left corner, it generally closes the app window and the app continues to run in the background. This is also evident by the app icon visible on the dock with the dot indicator below it. If I click the app icon on the dock and then launch it, the NSWorkspaceDidLaunchApplicationNotification event won’t be triggered.
To track such events, I tried using the NSWorkspaceDidActivateApplicationNotification event. Using this event, I was able to detect all the app launch scenarios. The problem is that this event gets triggered whenever the app comes into focus such as switching windows using command+tab, clicking on its dock icon, changing between two apps, …
Is there a way to filter out these triggers or identify which action led to the trigger? Or is there some other event/ method I can listen to which gives the required filtered triggers? I only want to detect scenarios where a new window of the app is created.
What you seems to want is two different things, as was mentioned in comments, which should be processed separately to be reached.
To detect app launch, when the new process is started. You could use the NSWorkspaceDidLaunchApplicationNotification if it is enough (usually for visual user apps), or kqueue if it is not, or even EndpointSecurity framework to rule them all.
To track the window(s) in the already launched app. Visually, if the white dot under app dock icon is there, the app is still launched.
There is an Accessibility framework for this task, you could track the event of window creation, window destruction, get count of windows from target process id, visibility state and etc.
It is a bit abandoned and has no updates since maybe release, but it will work for you in most cases.
I'm developing an application in which, if I press a combination of keys shows me a popup inside the form of another external application, I mean something like the "windows game menu", but I have no idea how to show the popup in the external application. I leave you an image to make you understand what I mean as a popup. sorry for my english but I do not speak.
Thanks in advance
You cannot control one application form of another application without having access to its code or knowing if a queue messaging command has been set for doing it.
It is possible to program a window of your application to be shown over any other , likely this will not be working over a Directx - OpenGL full-area, i.e. when you are playing a videogame that is using the same functionality because the last one is winning.
In this case your popup will be visible barely as a flick, but considering standard form application you can make it to stand over by working with userd32.dll method
"SetWindowPos" with the flag HWND_TOPMOST.
You will need first to detect the position of the application window, or if it is a fullscreen one you can simply detect the size of the screen and consider to place it in the center, then you can set the position of your application form "pop-up".
Details about the SetWindowPos , which is among windwows base dll but can be invoked from .net here below:
https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowpos
Make a window topmost using a window handle
Requirements:
Our application replaces the usual windows shell (explorer.exe). This is a product requirement for a closed system that we're supplying.
We oughtta let the user select a wi-fi network and connect to it.
The problem: The wi-fi networks dialog only shows up when explorer.exe is running
What we tried:
Write our own wi-fi manager that uses wlan API. It lists connectible networks and allows the user to connect/disconnect. Problem: too many network types/configuratons that have to be tested, especially when the wheel has already been invented and reinvented all over.
Try and check how is the networks dialog implemented. It appears that it's and undocumented COM interface (IUIRAdioManager). Problem: it's undocumented, so no API
Use an existing network manager, for instance the one that comes with the driver. Problems: it's ugly, not to the product's taste; and it opens too many options for the user, like creating and loading profiles, browsing for files on a file system - these things are unacceptable.
Running explorer.exe just for the purpose of showing the networks dialog and then killing it. Problem: once we run explorer.exe - it pops up metro view and hides our fullscreen application or shows the taskbar.
The latter seems like the preferred solution: no need to reinvent the wheel, it does what's needed. Just gotta make explorer.exe not pop out, keep it quiet in the background.
So, we're down to two options:
How to show the networks flyout dialog without explorer.exe?
How to run explorer.exe without it popping out metro or taskbar above our application?
Your first solution would be incredibly difficult to implement. I am almost certain that the Networks window is dependent on explorer.
However, your second is entirely possible.
To hide the taskbar, you will need to find a window (using FindWindowEx) to find the taskbar (name is Shell_traywnd). This will hide the taskbar and start button. EDIT: Unless you are implementing your own taskbar, you might want to set the taskbar to autohide.
Next you will need to hide all of the metro programs. In a similar fashion as above, find the class named EdgeUiInputWndClass and close it. You should be able to get the process name of it and then kill the process.
Windows key. This is a little more difficult. You will probably need to use a program and delete the key or a keyboard hook (a low level keyboard hook) and just ignore key presses with the same scancode as the windows key. Left Windows is 0x5b and Right is 0x5c (source). Note that this will not block Ctrl+Alt+Del.
Finally, to show the Flyout, you can run %windir%\explorer.exe shell:::{38A98528-6CBF-4CA9-8DC0-B1E1D10F7B1B}
(source).
EDIT2:
You should also be able to hide toast notifications via this
Of course, I don't see why you cannot just use Windows 8/8.1 and put the app in kiosk mode.
I am making a vim-style "window manager" that takes text input, much like Alfred or Spotlight in Mavericks (in a floating panel).
The problem I'm having is when I call activateWithOptions: on a running application it steals focus from my window. I was hoping the problem would be solved by simply bring my app to the foreground again, however it seems the activation is running on a separate thread, and I end up activating my app before the original app gets activated.
I have tried reactivating when I receive NSWorkspaceDidActivateApplicationNotification, but that doesn't work either.
Ideally I'd like to pause execution until the application is focused for multiple reasons, since that would be the window I manipulate further.
Does anyone have any suggestions?
I am developing an app that allows the user to make certain changes to tiles on the Windows 8 start screen. When a change has been made within the app, the user will be shown a "View my changes" button. Clicking the button should bring the user back to the start screen.
I have looked into different ways of closing/suspending the app programmatically (and thus taking the user to the start screen), but I have not found a way to achieve this using WinJS. Throwing an exception closes the app, but this seems like a very dirty workaround. Any suggestions?
I'm assuming you are creating secondary tiles and want to show the users what they look like? #mydogisbox is right in that this kind of functionality has probably been deliberatly excluded.
I'd recommend to just do an in-app 'view changes' of whatever changes to secondary tiles the user might have made. In general, I'd argue that this would be a better user experience because you will keep the user engaged within your application and not be essentially kicking them out of the experience.