X11 event when app loses focus - c

Is there an XAppFocusOut event similar to Windows WM_ACTIVATEAPP
or OSX's applicationDidResignActive or some other way to get notified when an app loses focus? XCB solution preferred.
To clarify: I'm interested in an event when the app, not a window loses focus.
Thank you.

You want the FocusOut X event.
The X server can report FocusIn or FocusOut events to clients wanting
information about when the input focus changes. The keyboard is always
attached to some window (typically, the root window or a top-level
window), which is called the focus window. The focus window and the
position of the pointer determine the window that receives keyboard
input. Clients may need to know when the input focus changes to
control highlighting of areas on the screen.
To receive FocusIn or FocusOut events, set the FocusChangeMask bit in
the event-mask attribute of the window.

Related

Why doesn't ResizeBegin get called for a maximized MDIChild?

In Winforms if the MDI child window is maximized it doesn't receive ResizeBegin (or ResizeEnd) events. It does receive Resize events - why the distinction? If the child isn't maximized it does get ResizeBegin/End events. Is there a nice way around this? There are plenty of ugly ways: calling directly from the MDI container ResizeBegin event to the child for example.
The ResizeBegin/End events are generated when the user starts and stops resizing a window. Implemented by a modal loop inside Windows itself, it keeps the window edge following the mouse cursor when the user moves it. ResizeBegin when he clicks a window edge, ResizeEnd when he releases the mouse button.
Clearly no user is involved when you change the Size or ClientSize property of an MDI child window in your code. So no Begin or End, just the Resize event. And just one Resize event trigger, there's no constant train of them like there will be when the user uses the mouse to resize. Which otherwise explains why Begin/End is important, if you do a lot of work in your Resize event handler then you'll bog down the UI pretty heavily. Common with automatic layout, the visible artifacts are not pretty.
If you really have to then you can simply generate the event yourself. Call OnResizeBegin() before, OnResizeEnd() after you change the window's Client/Size property value. That code needs to live inside the window you resize to get the correct event triggered. Pretty unlikely you should be doing this btw. Do beware that MDI automatically resizes an maximized MDI child window, it of course cannot be maximized anymore when you activate another one. You can't wrap that with OnResizeBegin/End() calls.

Capture all Click or Touch events recursively in WPF

am pretty new to WPF, but am looking to capture whenever anyone touches inside a window or any child controls.
If I capture the click event for a Window, only the windows inner space capture the click. It's child controls do not.
How do i recursively capture any click/touch event ANYWHERE on the screen in a full size window?
many thanks in advance
The routed event handling implementation in WPF is intended to give all controls in a nested hierarchy a chance to intercept and handle touch & mouse events. However, controls have the ability to prevent children from receiving the event notification.
There's a pretty good explanation of event routing here: http://nui.joshland.org/2010/04/why-wont-wpf-controls-work-with-touch.html
All controls receive a Preview event (for click or touch), and this cannot be prevented. After this, the event is 'promoted' to a regular Mouse/Touch event (touch is handled before click) However, if any control in the hierarchy for the 'click' (_MouseDown in WPF) event handling sets the Handled property on the event args to true, then the event will not be propagated any further.
Unless you are handling touch events or manipulations, or explicitly setting e.Handled = true in your code, then all controls in a nested stack should receive the _MouseDown event.
As noted in the comments below, some controls will set 'Handled = true' which would prevent their containers from receiving corresponding _TouchDown or _MouseDown events. However, they would all receive a PreviewTouch/PreviewMouseDown first.
Also note that handling touch events prevents handling of mouse events.

Event called by the control or its Parent control

If there is a button within a group box on a win form, and when the "click" event occurs, then who is actually calling the Event. Is it the button contorl or its parent i.e. GroupBox.
If you'd have written a native Windows GUI program then it would be the group box that got the click message. Buttons send notification to their parents. But that gets re-routed in Winforms, both through sub-classing and having the container window reflect messages back to the child control.
Events always originate at the control. Their OnClick() method in case of a click. You however still handle the event at a higher level window. Typically the form, not the groupbox. The sender argument of the event handler passes a reference to the control. Having a choice over exactly where you handle the event is a major advantage over the native way. It makes controls highly adaptable and composable.

WPF: Detect when Window loses focus

How do I detect when my window loses focus?
Use the Window.Deactivated event.
You may be looking for the Application.Deactivated event, which fires only if the user switched to a different application.

Closing a window when it's "no longer needed"

This is kind of a hard question to describe, and I've searched for about an hour now to no avail.
Essentially, picture a small 'flyout' window like the Windows 7 Wireless Control or the Volume Slider from the system tray(notification area). When you click on the icon, the application pops up with focus, and if you click off of it, the window destroys itself.
I thought it woudl be easily solved by simply having my window destroy it self when it loses focus (I've been listening for WM_KILLFOCUS), but the problem is, if the icon is clicked, my window does not always get focus. Since this isn't the case, if the user clicks my icon, and then clicks away because it was a mistake (on the desktop say), then how can I set my app to close?
I've tried messing with SPY++ but checking the volume control / wireless control apps are proving difficult as they disappear when I try to get their window/process handles.
Thanks!
The usual way this is implemented is by starting a timer on the window creation. If the window gets the focus before the timer has triggered, this means the user has interacted with the window. In this case, the window will just stop the timer and will destroy itself when it loses the focus. In the case the window did not get the focus before the timer was triggered, the window will destroy itself on the timer event.
This is also usually combined with opacity animation, so that the window is fading out while waiting for the user. Sort of a visual feedback to the user that it will be soon gone. However, the opacity animation is used mostly for notification toasts, and is rarely used for control windows like the volume control.
The alternative is to force set the focus in your window when the user interacts with your systray icon.
Also note that if your window is a top-level window, the preferred message to listen is not WM_KILLFOCUS, but WM_ACTIVATE and WM_MOUSEACTIVATE. You can also listen to WM_NCACTIVATE, but that one has some specifics, if you are doing a custom non-client area.
Update: You can set the focus to your window by calling either SetActiveWindow or SetFocus on it when you create it (or when you make it visible, if you're hiding it).
A long, long time ago I wrote a drop-in replacement for the Windows 3.1 Task Manager that accomplished this by handling WM_ACTIVATEAPP. Give that a try.
Have you looked into the Popup? That one will disappear once you click outside it (unless you set StaysOpen to true).

Resources