How to tell if a control is no longer visible to the user? - windows-runtime

I have a control in which I repeatedly run some animations (e.g. DoubleAnimation). Can I detect if my control is no longer visible to the user? E.g it gets scrolled away from, the user navigates forward to another page, or it gets obscured behind other controls.
I don't want to run those animations unless at least some part of my control is visible for the user.

You could analyze the visual tree or get a transform from control coordinates to screen coordinates to see if its positioning is within the view port and also check things like opacities, visibilities etc. of controls down the visual tree path, but that is so processing intensive that it is not worth doing all the time for a general solution.
The only thing that would make sense is to handle the ScrollViewer.ViewChanged event and check if the offsets make it visible or not while limiting the TransformToVisual or VisualTreeHelper calls only to times when the actual layout within your ScrollViewer changes.

Related

Does preventing a modal from being hidden by clicking the background violate accessibility requirements?

I'm adding a blocking modal (ie one that covers the screen and prevents interaction while an API call is processing) to my company's design library.
As part of that, I modified our modal so that clicking on the grey backdrop will NOT hide the blocking modal, but I want to make sure that doesn't violate accessibility guidelines. I haven't been able to find anything online about this. Does anyone know if this this violates accessibility requirements?
Short Answer
The answer is 'it depends'. Basically if the modal is not dismissable in any way it becomes a 'keyboard trap' and so would violate WCAG.
However if you structure it correctly a modal that blocks the page while an API loads is perfectly valid (and can't be dismissed while the page is loading), but there are a few things you need to do to make sure this is accessible.
1. Make sure that when this modal loads, nothing else on the page is focusable.
The biggest issue I see on most modals is that they allow focus outside of them.
You can't just stop users using the tab key as that is not how most screen reader users navigate the page (they use shortcuts for headings (h1-h6), hyperlinks etc.).
For this reason make sure your modal sits outside of your <main> and the hide your <main> and other major landmarks that contain information with aria-hidden="true" and by adding tabindex="-1" to them so nothing is focusable.
Obviously this depends on your document structure so you would need to test it, but a properly structured HTML document will work with the above method.
2. Make sure that a screen reader user knows that the page is busy and something is loading.
There are a couple of ways to do this. The best is to use an aria-live region
Adding aria-live="polite" and aria-busy="true" to the section you are updating is one way (if you are updating one part of the page).
However in your circumstances I would make a section within the modal aria-live="assertive" and not use the aria-busy (as you will be hiding all the content in step 1 so aria-busy would not be applicable).
I would then update the message every second or two for long loads (i.e. 'loading', 'still loading', 'nearly loaded' etc. Or better yet a loading percentage if your script allows.)
Once the page content has loaded, you do not need to say 'loaded' instead make sure you have a heading for the section or page that has a tabindex="-1" added on it that accurately describes the content that has just been loaded in.
Once the load completes, programatically focus this heading and the user will know that the load is complete.
3. Make sure that if the API call fails you feed something meaningful back to screen readers
When your API call fails (notice I said when, not if!) make sure your JavaScript can handle this in a graceful way.
Provide a meaningful message within your modal aria-live region that explains the problem. Try to avoid stating error codes (or keep them short, nothing worse than hearing a 16 digit string on a screen reader for an error code), but instead keep it simple such as 'resource busy, try again later' or 'no data received, please try again' etc.
Within that region I would also add one or two buttons that allow to retry / go back / navigate to a new page depending on what is appropriate for your needs.
4. For long load times, let the user know what is happening.
I covered this in point 2 but just to emphasise it, make sure you feedback to users that things are still loading if there is a long load time by updating your aria-live region.
Nothing worse that wondering if the page has loaded and the developers forgot to tell you.
5. Give the option to cancel an API call so it doesn't become a keyboard trap.
Obviously the big problem with a whole page modal is it is a 'keyboard trap'.
To ensure this isn't an issue make sure you provide a cancel button.
Make sure it is clear that this will cancel the loading of the page, but don't rely on JavaScript alone.
Instead make this a <a> styled like a button that either points to the current page or the previous page (yet again depending on your needs) and add role="button".
Then intercept this click with JavaScript so that it can function like a button.
The reason for this is that when your JavaScript fails (yet again - when, not if) the user still has a way to get to a meaningful page, thus avoiding a keyboard trap.
This is one of the few times you should use an anchor as a button, as a fallback!
By doing this you ensure that the user always has a way to escape the modal.
You may also consider allowing a user to use the Esc key to close / cancel but that is yet again down to you and your circumstances.

GTK window, how to get window decoration sizes?

I am looking for an equivalent of AdjustWindowRect function that allows to get widths/heights of window caption and borders.
Do we have this functionality in GTK 3 at all? Seems like not.
I've looked through all gtk_window_xxx, gtk_widget_xxx and gdk_window_xxx* functions...
Update:
In principle I am able to determine window-chrome/decoration dimensions as a delta of gdk_window_get_frame_extents() and gtk_widget_get_allocation() / gdk_window_get_origin() but
it works only after window appeared on the screen. I need it before that - to calculate initial window position.
it is really a hack.
It's up to Window Manager to decide.
You can request it by sending a message _NET_REQUEST_FRAME_EXTENTS as explained in the specification of EWMH (Extended Window Manager Hints):
_NET_REQUEST_FRAME_EXTENTS
window = window for which to set _NET_FRAME_EXTENTS
message_type = _NET_REQUEST_FRAME_EXTENTS
A Client whose window has not yet been mapped can request of the
Window Manager an estimate of the frame extents it will be given upon
mapping. To retrieve such an estimate, the Client MUST send a
_NET_REQUEST_FRAME_EXTENTS message to the root window. The Window Manager MUST respond by estimating the prospective frame extents and
setting the window's _NET_FRAME_EXTENTS property accordingly. The
Client MUST handle the resulting _NET_FRAME_EXTENTS PropertyNotify
event. So that the Window Manager has a good basis for estimation, the
Client MUST set any window properties it intends to set before sending
this message. The Client MUST be able to cope with imperfect
estimates.
Rationale: A client cannot calculate the dimensions of its window's
frame before the window is mapped, but some toolkits need this
information. Asking the window manager for an estimate of the extents
is a workable solution. The estimate may depend on the current theme,
font sizes or other window properties. The client can track changes to
the frame's dimensions by listening for _NET_FRAME_EXTENTS
PropertyNotify events.
https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472648576
So, in two words, you send a _NET_REQUEST_FRAME_EXTENTS msg to WM (to the root window - it's gdk_get_default_root_window() in case of gdk), then wait for the reply (_NET_FRAME_EXTENTS PropertyNotify), and get the desired data from your window's _NET_FRAME_EXTENTS property.
Unfortunately situation with GTK is even worse than just problem of getting decorations.
The first:
gtk_window_move(window, x, y) sets border frame position of the window.
And gtk_window_resize(window, w, h) sets client dimensions of the window.
And there is absolutely no way in GTK API to set border frame size programmatically and explicitly. And so there is no way to set window frame position/size of decorated windows.
On Windows and MacOS, using their APIs, that is easy to do, and reliably. But on GTK they only have this:
gtk_window_move(): Begs the window manager to move window to the
given position. Window managers are free to ignore this; most window
managers ignore requests for initial window positions (instead using a
user-defined placement algorithm) and honor requests after the window
has already been shown.
You are correct that the functionality is not there. GTK is agnostic of the decorations that the window manager places on the window; for all that your application is aware of, there may be giant decorations, or there may be none.
What you can do, is use gtk_window_set_titlebar() to tell the window manager to let you use your own decorations; then you have full control over their size.
For what it's worth, AdjustWindowRect() and AdjustWindowRectEx() assume that you are working purely with the default Windows window decorations and, optionally, one row of default Windows menus. It's not suitable for custom window decoration or multiple rows of menus; in these cases, you use the WM_NCCALCSIZE message, which has to be sent to a specific window. DefWindowProc() does all the work for you if you just want the defaults. (Example for multi-row menus. And if you aren't using default Windows menus, then just tell Windows that you aren't; you'll be responsible for positioning everything yourself in this case. GtkMenuBar works on this principle too.)
Since you want the default decorations, though, you merely luck out in that Windows provides an AdjustWindowRect() function in the first place, and that it will work for the default window decoration because it's provided by Windows.
(It is entirely possible for a program to lie in its WM_NCCALCSIZE, but it'd be lying to Windows as well, and Windows does not like a liar. I imagine the same would hold for _NET_REQUEST_FRAME_EXTENTS, though I'm not sure how bad the damage would be in that case.)
So the fact that X11 doesn't have this guarantee that all window managers must follow means you're out of luck in that department. (In fact, I don't think Wayland has such a thing either; does it?) Hell, nothing prevents a window manager from not having window decorations at all. Or you can even not run a window manager in the first place!
In theory, you could compare the size and position of a window (either the geometry of the GdkWindow or the allocation of the GtkWindow) with and without CSD to see what space you lost. But I don't know if this is reliable. A GTK+ developer will need to confirm.

Reliably detect if a user is using a mouse on a webpage?

On our page we have some iframes in a long horizontally-scrolling <div>. If the user is using a mouse they can scroll with the scrollbars and we would like them to be able to select text within the iframes. If they are using touch only however, the scrollbars are a hassle and I would like to overlay a transparent element over the whole thing to give them the ability to scroll easily by dragging, this of course sacrifices the select-text feature but makes sense in that scenario.
Which gets me to my question, is there a way to reliably detect if a user is interacting with a webpage via a mouse?
Everything I've seen on detecting touch or mouse is that touch will broadcast mouse events so it is very difficult to detect touch OR mouse (not to mention that you can have both). My problem is simpler - it is whether the user has interacted with the page via a mouse.
Can anyone think of a way to check this reliably?
A mouse can do one single thing a touch device can never do - move without having any buttons pressed. So I'd just install an onMouseMove event on page load, and if it triggers without buttons pressed mark the user as a mouse user. You could then persist this through a cookie or LocalStorage since the flag will not change within the same environment, and remove the event right away. The precise way of implementing the single-fire event depends on which library you use (if any at all), but it should be easy with Mootools/JQuery docs in hand.
In general I'd recommend the easier route of just checking for a touch interface in most cases :
if('ontouchstart'in window)
{
/* it's a touch device */
}

swing: saving dialog box resize dimensions

I have a dialog box with a bunch of dimensions that a user can change by moving/dragging, including a JTable with resizable/draggable columns.
What I would like to do is to make the state of these resizable columns / dialog boxes / etc. persistent, so the next time my application starts up, the user doesn't have to go through the resizing step all over again.
What's the most convenient way to do this?
You should probably take a look at the code in (the now probably dead) JSR-296. A part of it was focused on persistent session state, and I know for sure that the code for persisting window locations and such was already functional and in the basic framework. It should either already do what you want, or provide a good starting point.
Cfr. dev.java.net site for JSR-296

Block Access mousewheel behavior in external ActiveX controls

In an Access (2002 / 2003) data-bound form, a turn of the mousewheel moves to the next/previous record, even if the cursor is inside a multiline text field or a listbox. This is a major annoyance to users and cannot be turned off easily.
I recently discovered a DLL called MouseHook (http://www.lebans.com/mousewheelonoff.htm) which can effectively block this mousewheel behavior and replace it with more expected behavior.
However, when an external ActiveX control is added to an Access form, this module does nothing. For example, I have a form with a FlexGrid control on it, and it can contain a lot of rows. When a user tries to scroll in there using the mousewheel, Access again simply goes to another record instead, even with MouseHook DLL loaded.
Is there a solution like MouseHook DLL but which also works for external ActiveX controls? Or is the source code of the MouseHook DLL available so it can be modified to deal with controls like FlexGrid?
PS: I wanted to ask the author of MouseHook DLL, but he is currently "on a hiatus" until June 2009.
If you really have to alter the UI and change how the user expects the mouse wheel to work, I would actually recommend just disabling it rather than altering how it scrolls. While it's scrolling may seem odd to you, it is how the program works. What would you do if you had to read PDF's all day, and then one day one person decided that the way the mouse wheel scrolling worked wasn't good enough and changed to so it defaulted to huge jumps or horizontal or whatever. Yes, it may have been a better solution, however it is annoying to the user because it doesn't do what it is supposed to do.
Why are you using a flexgrid in Access? To me, this is a read flag that you likely are approaching the project with an Access-hostile point of view, since you seem to be choosing non-native controls to do things that are almost always much more easily accomplished with Access's native controls.
Hook the flexgrid, intercept the WM_MOUSEWHEEL message, ignore it and call your intended behaviour.
Not a direct answer to your question, but the way we deal with the mouse wheel movement is to prevent accidental changes of records after the user has started editing. When the user opens the form, the wheel moves the records willy-nilly as normal. As soon the user edits something on the field, and then moves the mouse wheel, the BeforeUpdate event fires, which causes our code to put up a prompt saying they must save the record first. We have a save button which the user must explicitly press to supress the warning in the BeforeUpdate event.