Application.application.nativeWindow.activate() problem on Windows - apache-flex

I have an AIR application with a system tray icon. When clicked it shows and activates the app. This is working as expected when the app is hidden (docked), however if I select another application so my app is in the background clicking on the system tray icon does nothing.
Oddly I also have a contextual menu on the system tray icon, which has an option to restore, this calls the same event handler as ScreenMouseEvent.CLICK, yet works.
I expect it's something to do with the contextual menu changing the focus, perhaps it's a bug in how AIR works with the system tray, perhaps it's just something I'm missing. Would be good to know if that's the case.
Thanks in advance
Rob

//instead of just calling
activate();
//call
nativeApplication.activate()
//or even better
nativeApplication.activate(nativeWindow);
Update based on OP's input: if you have multiple windows open for the application, use:
nativeApplication.activate(nativeApplication.openedWindows[0]);
If you are not in the main WindowedApplication class, you can use the static property NativeApplication.nativeApplication to get a reference to the singleton object.
WindowedApplication.activate()
Activates the underlying NativeWindow (even if this application is not the active one).
NativeApplication.activate(window:NativeWindow = null)
Activates this application. If the operating system allows activation, then the specified window is activated and brought to the desktop foreground; that is, in front of the windows of other applications. (If the window parameter is null, then a visible window of this application is activated.)
livedocs is not clear on why this is happening. It says activate() activates the underlying native window - one would expect it to be brought to the front when it is activated, but that's not happening.

Related

Java FX 8 Popup does not move focus back to application

I have a Java FX application in which I show a Popup that contains a text field. I intentionally keep this popup visible even when the user clicks away from it. This works fine except for one case:
When the user has focus on the text field in the Popup, then clicks on a separate application, and then clicks back onto the text field. The FX application does not regain focus from the OS. If the user types on the keyboard, the other application will still receive the keyboard input. To work around this, the user has to click on the main FX application window outside of the popup.
The strange thing is that, in debugging, I can see that the text field in the Popup is getting focus, but the OS does not show that the FX application is now in focus. Is there a way that I can force the OS to move focus to my application?
This occurs on Windows and Mac. I tested with jdk 8 update 45 and jdk 8 update 92.
I did a test with a minimum Popup:
static class TestPopup extends Popup {
TestPopup() {
content.add(new TextField("Hello"))
}
}
and I show it by calling:
new TestPopup().show(somePaneInMainWindow, 0, 0)
After some research I found that this is expected behavior.
Answer found here:
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8123137
From the link:
This is the right behavior. All the JavaFX popup windows are
unfocusable, so they can receive input only if the owner window is
currently focused. Usually popups are set to auto hide, when the owner
gets unfocused, but this is not the case in this test, so the popup
just stays around.

Custom Touch behavior in Windows 7 with Qt/QML application

I am developing a touch application for Windows 7 with Qt/QML. The end-user-device has Windows 7's native touch behavior, i.e.: When touching the screen, a point appears on the last-touched-point, and when ending the physical touch, Windows puts that point on the now-touched point and runs in the on-clicked-Event.
Compared to the behavior one knows from standard Windows mouse-usage, this leads to a different behavior as soon as it comes to e.g. clicking some button: A mouse user will expect that the button changes color to the pressed-down-color when mouse button goes down, while the color changes to the default color again when the mouse button goes up.
In my application, I want to have a customized way of touch feedback: What is currently being touched should be marked using changed colors of buttons, imitating a "mouse goes down" when the actual physical touch begins and imitating a "mouse goes up" when the actual physical touch ends.
My application will run fullscreen, so an actual possibility would be to change the system's behavior on application start and change it back to default on applications end.
Such a behavior would effectively be the same as the standard behavior on e.g. all Android devices I know.
I searched through all the MouseArea and MultiPointTouchArea elements, trying to find a way to just make the click-reaction behavior different to the standard behavior. However I did not even find a way to capture the begin of the actual touch ... All the things which I want to happen at the begin of the touch actually happen when the touching ends.
Edit:
It does not matter if I use a QML button or a mousearea plus the MouseArea.pressed property: Nothing will be "pressed" before the finger leaves the touch and the onClicked() even is called.
Possibly related:
Adobe AIR: touch screen doesn't trigger mouse down event correctly - but I did not find a way to access the functions like Multitouch.inputMode (which are mentioned in the first reply) from a native Qt application.
How can I achieve the described behavior for my application?
The solution for this issue is to disable "Press and Hold" for the application. This is what can be done in a system-wide setting using ...
Control Panel -> Pen and Touch -> Touch -> Press and Hold -> Settings -> uncheck 'Enable press and hold for right-clicking'
The only solution I found to to this in native code can be found here:
http://msdn.microsoft.com/en-us/library/ms812373.aspx
I checked that this is at least still working for Windows 7. To get it working for QML, I searched for the QWindow* in QQmlApplicationEngine::rootObjects() and used its winId as a HWND. With that HWND, I called the TogglePressAndHold function from the link before app.exec().

Straightforward way to count number of windows up through PopUpManager?

I'm using the PopUpManager to bring a bunch of event windows up.
I want to make it so that only one window can be open at a time, but I don't see anywhere in the code that tracks open windows to set up a conditional. I guess it just creates the windows and then sets them free?
Thinking about a windowCount variable that increments when I add a window and decrements when I remove one, but since the PopupManager is called in different classes I'd have to start throwing events all over the place. I can do that, but I'm wondering if there's a more straightforward method?
The systemManager (rather than PopUpManager, go figure...) provides information on the currently opened popup windows.
If your popups are all model then you will be interested in 'systemManager.numModalWindows':
The number of modal windows. Modal
windows don't allow clicking in
another windows which would normally
activate the FocusManager in that
window. The PopUpManager modifies this
count as it creates and destroys modal
windows.
Otherwise try out 'systemManager.popUpChildren':
An list of the topMost (popup) windows
being parented by this ISystemManager.
An ISystemManager has various types of
children, such as the Application,
popups, tooltips, and custom cursors.
You can access the top-most windows
through the popUpChildren property.
The IChildList object has methods like
getChildAt() and properties like
numChildren. For example,
popUpChildren.numChildren gives the
number of topmost windows and you can
access them as
popUpChildren.getChildAt(i).
I see a few options:
1) Make all your windows modal; so that the application can't be used until the window is closed. This is a argument to the createPopUp method on the PopUpManager. Presumably you do not have Popups creating other popups.
2) Create your own Manager class, possibly an extension of the PopUpManager class that keeps track of all open windows. Then you'd have a single source of all PopUps and could maintain them that way.

Flex-AIR: Make application with NO tab in taskbar?

I have an AIR app about half way done right now. I was informed by the client today that he does not want a tab to show up in his task bar. I already have this in place for new windows by making them lightweight. I do not know how to make the main window lightweight though. If there is not a way, is there a work around, like not not having a main window and just opening lightweight windows, don't know how that could be done either though? Anyone know how to do this?
Thanks!
Check this doc out. -- Yes, you can do this. In short, you have to hide the initial window - then display your application in a lightweight window.
Also - do note: On a Mac - the behavior is different. By convention, a window is not shown in the 'task bar' when it is displayed. When it is minimized it is in the bar. To hide the application when minimized on a Mac - you have to make the window 'invisible' instead of minimizing it. The doc mentioned above gives further details.
The key part of the doc for your case:
On the Windows operating system,
windows created with the types utility
or lightweight do not appear on the
taskbar. Invisible windows do not
appear on the taskbar, either.
Because the initial window is
necessarily of type, normal, in order
to create an application without any
windows appearing in the taskbar, you
must either close the inital window or
leave it invisible.
To close all
windows in your application without
terminating the application, set the
autoExit property of the
NativeApplication object to false
before closing the last window. To
simply prevent the intial window from
ever becoming visible, add
false to the
element of the
application descriptor file (and do
not set the visible property to true
or call the activate() method of the
window).
In new windows opened by the
application, set the type property of
the NativeWindowInitOption object
passed to the window constructor to
NativeWindowType.UTILITY or
NativeWindowType.LIGHTWEIGHT.

how to keep a nativewindow on top

I need to keep a NativeWindow I am creating on top of the main window of the application.
Currently I am using alwaysInFront = true, which is not limited to the windows in the application. I can successfully synchronize the minimize/restore/move/resize actions, so the top window behaves appropriately in those cases. Even though using this option has the drawback that if I alt-tab to other application the window goes on top of the other application.
Because of the above I am trying to get it to work without using the alwaysInFront. I have tried using orderInFrontOf and orderToFront, which gets it in place but when I click an area in the main window the top one becomes hidden i.e. air makes it the top one.
I have tried capturing activate/deactivate events but it only happens on the first click, so on the second click the top window becomes hidden again. I also tried making the top window active when the main one becomes active, but that causes the main one to loose focus and I can't click on anything.
Ps. I am doing this to improve the behavior of a HTMLOverlay I am using - see Flex Air HTMLLoader blank pop up window when flash content is loaded
Listening for Event.DEACTIVATE and calling event.preventDefault() should work. Not sure if that is what you have tried, but I have an app where that does the trick.
I ended up turning on/off the alwaysInFront option based on whether the main window or the top window were active i.e. if none where active I turned it off. This was additionally to what I mentioned in the question.
That way when the user switches to another application, the window doesn't go on top of the other apps. I still would prefer a solution where I don't have to use the alwaysInFront option, or even better an alternate solution to the flex loading flash in external sites issue I linked to above.
Ps. I will try to check with the owner of the HTMLOverlay to submit a patch (its an improvement, although its tied to an app that doesn't open extra windows when opening the overlay).
Update: I have committed the changes to the HTMLOverlay.
I'm trying to do something very similar. In an AIR application, I have one large full screen window which is essentially the "desktop". I always want this window to stay behind all other windows in my app. There are, however, some items on the "desktop" window that need to be clickable.
There appears to be no clean way to force a window to maintain its position in the window ordering.
What I've settled on so far, which isn't perfect, is to make all other windows in my app use the alwaysOnTop property but bind this to a global var (ugh) that I maintain to track the overall application level active/inactive state. This way, when I switch to another app, my windows don't float above the all other app windows - they correctly move behind as expected.
Then, I have a regular (alwaysOnTop=false) window that is fully transparent as an "overlay" to the desktop window on which I can place various interactive controls. This window is OK to come forward since it's transparent and my other windows are alwaysOnTop.
Finally, and crucially, I install three event listeners on the "desktop" window as follows:
protected function onApplicationComplete(event:Event):void
{
this.addEventListener(MouseEvent.MOUSE_DOWN, onClickHandler, true,1000,true);
this.addEventListener(MouseEvent.CLICK, onClickHandler, true,1000,true);
this.nativeWindow.addEventListener(Event.ACTIVATE, onActivateWindow,false,-1);
}
protected function onActivateWindow(event:Event):void
{
trace("sent via activate to back");
orderInBackOf(bigTransparentWindow);
}
protected function onClickHandler(event:MouseEvent):void
{
trace("sent via click to back");
orderInBackOf(bigTransparentWindow);
}
I'm not entirely happy with all this since there is still some occasionally noticeable flicker of objects in the overlay window - it appears that the "Desktop" window gets ordered in front of it, an update of some sort happens, and then it gets forced behind again.
Any better solutions welcome!

Resources