Why does a browser repaint require re-checking the visibility of all DOM nodes? - browser

Recently I read this description of the browser repaint process:
A repaint occurs when changes are made to elements that affect visibility but not the layout. For example, opacity, background-color, visibility, and outline. Repaints are expensive because the browser must check the visibility of all other nodes in the DOM — one or more may have become visible beneath the changed element.
I was a little surprised by the last sentence. Why must a (Webkit-based) browser re-check the visibility of all nodes in the render tree for any and every repaint? Even of an item in its own render layer?

Related

How to animate resize/reposition of a Flutter Column when a child is added with a ScaleTransition

I'm implementing a login screen. It has a centred Column containing a TextField for entering an email address and a number of buttons for social sign-in. When a button is pressed, the Column is rebuilt with a CircularProgressIndicator (spinner) added at the bottom. I've wrapped the spinner in a custom widget that manages a ScaleTransition animation. That works OK, but the Column grows and shifts up to accommodate the final full size of the spinner immediately instead of moving smoothly with the animation.
I also wrapped the Column in an AnimatedSize widget using the same curve and duration as the ScaleTransition, but it hasn't helped. The root of the tree is a Consumer of the state that triggers the addition of the spinner so the animations should both be starting together. Maybe the the spinner needs to be permanent for this to work, but it doesn't seem desirable because its API doesn't provide a way to pause the animation. It would presumably constantly use some power to animate itself even when it isn't visible. I'm fussy about that sort of thing.
It looks like I might have to use an AnimatedList, but it doesn't seem semantically correct because the contents aren't really a list. So is there a more generic way to animate the size (and position) of parent widgets like Column and Center to track an animated size change of their children?

How to differentiate between reflow and repaint in chrome developer tools?

How to differentiate between repaint
A repaint occurs when changes are made to elements that affect
visibility but not the layout. For example, opacity, background-color,
visibility, and outline. Repaints are expensive because the browser
must check the visibility of all other nodes in the DOM — one or more
may have become visible beneath the changed element.
and reflow
Reflows have a bigger impact. This refers to the re-calculation of
positions and dimensions of all elements, which leads to re-rendering
part or all of the document. Changing a single element can affect all
children, ancestors, and siblings.
using chrome developer tools(or other similar tools)?
In Chrome Performance tab i see only repaint.
repaint

How to make an overlay which capture no events

I would like to draw some sort of window on top of all the other windows. For example, to display some debugging infos (like conky) or things like a timer.
The main thing is that I would like to able to continue using the other windows while using it (the events go through transparently).
I've tried doing it with pygtk, pyqt and others but can't find a way to make it a real overlay with no event capture.
Is there some low-level x11 solution?
I think the Composite-extension-approach will not work when a compositing manager is running (and thus Composite's overlay window is already used).
Since you explicitly mention "no event capture":
The SHAPE extension allows to set some different shapes for a window. Version 1.1 of this extension added the "input" shape. Just setting this to an empty region should pretty much do what you want.
Some concrete example of exactly what I think you ask for can be found in Conky's source code: http://sources.debian.net/src/conky/1.10.3-1/src/x11.cc/?hl=769#L764-L781
Edit: Since you said that you didn't find anything in Gtk (well, PyGtk), here is the function that you need in Gtk: https://developer.gnome.org/gdk3/stable/gdk3-Windows.html#gdk-window-input-shape-combine-region
You might need Composite extension + GetOverlayWindow request:
Version 0.3 of the protocol adds the Composite Overlay Window, which
provides compositing managers with a surface on which to draw without
interference. This window is always above normal windows and is always
below the screen saver window. It is an InputOutput window whose width
and height are the screen dimensions. Its visual is the root visual
and its border width is zero. Attempts to redirect it using the
composite extension are ignored. This window does not appear in the
reply of the QueryTree request. It is also an override redirect
window. These last two features make it invisible to window managers
and other X11 clients. The only way to access the XID of this window
is via the CompositeGetOverlayWindow request. Initially, the Composite
Overlay Window is unmapped.
CompositeGetOverlayWindow returns the XID of the Composite Overlay
Window. If the window has not yet been mapped, it is mapped by this
request. When all clients who have called this request have terminated
their X11 connections the window is unmapped.
Composite managers may render directly to the Composite Overlay
Window, or they may reparent other windows to be children of this
window and render to these. Multiple clients may render to the
Composite Overlay Window, create child windows of it, reshape it, and
redefine its input region, but the specific arbitration rules followed
by these clients is not defined by this specification; these policies
should be defined by the clients themselves.
C api : XCompositeGetOverlayWindow
PyGTK Solution:
I think the composite and shapes X extensions are sufficiently ubiquitous and shall assume here that they are active on your system. Here's PyGtk code for this:
# avoid title bar and standard window minimize, maximize, close buttons
win.set_decorated(False)
# make the window stick above all others (super button will still override it in the z-order, which is fine)
win.set_keep_above(True)
# make events pass through
region = cairo.Region(cairo.RectangleInt(0, 0, 0, 0))
my_window.input_shape_combine_region(region)
win.show_all()
# set the entire window to be semi-transparent, if we like
win.set_opacity(0.2)
Basically what this does is tell Gtk that other than pixel (0,0) the entire window my_window should not be considered part of itself in terms of event propagation. That in turn, according to my current understanding means that when the pointer moves and clicks, the events go to the underlying window under the pointer position, as if my_window was not there.
Caveat:
This does allow your overlay window being the focus window (due to user-solicited window switching or just because it pops up and gets the focus when your application starts). Which means that for example, keyboard events will still undesirably go to it up until the user has clicked through it to make it lose focus in favor of whatever window is under the cursor. I would likely use the approach described here to iron out this aspect.
If there's a different and proper approach for making a portion of the screen "display stuff but not receive events", without building an oddball window like above over it, I'm happy to learn about it.
I assume that one's particular desktop environment (gnome, unity, etc. on linux) may interfere with this solution depending on version and configuration, on some occasions.

Web accessibility: does it make sense for focus to go to another element other than the whole page frame or the first focusable element on the page?

My question is about focus management for web accessibility. When we launch a popup/dialog, does focus always need to go to the first focusable element for accessibility reasons or is it acceptable to set focus on an element that we think the user is more likely to want to work with?
For example, if a dialog starts with an input field and a cancel link followed by a dropdown and we think the user would most likely want to work with the dropdown when the dialog loads, is it ok to set focus on the dropdown element? In this case, how would the user know about the previous focusable elements existing on the dialog? But, if the dropdown is where 80% of the users will want to be when the dialog is launched, it doesn't make much sense placing focus on the initial input field...
thoughts?
Based on my research and what public opinion is: http://webaim.org/discussion/mail_thread?thread=5435 it seems like where the focus goes for a modal dialog/popup would depend on the usecase. For example, it makes sense to set focus on the search input field for www.google.com although there are preceding elements that the user can interact with -- this maximizes usability for screen reader and keyboard only users. But, in general the focus needs to go to the first element the user can interact with -- depends on the scenario.
I would caution against setting focus to anything other than the first form element or headings/content that introduce the form. See WCAG 2.0 Focus Order:
If a Web page can be navigated sequentially and the navigation
sequences affect meaning or operation, focusable components receive
focus in an order that preserves meaning and operability. (Level A)
While the case you present is I think an edge case, I think the focus order rules still apply. If you think that most users will want to interact with the select why not put it first in the form rather than set focus to an element in the middle of the form?

Silverlight 3 - Elements inside an element dont arrange sometimes

I have a grid/canvas that has an element (say an icon with an image and text overlayed) added to it dynamically via code.
Most of the time it renders correctly when added (content is aligned properly inside it),
but sometimes all the content sits in one corner.
I can remove/add/remove/add/remove/add and it will eventually do it
After a movement of the parent canvas, the element corrects itself as if the layout has been updated.
I have tried the following on Loaded and OnApplyTemplate for both the element and the element parent but it still seems to happen occasionally
InvalidateMeasure()
InvalidateArrange()
UpdateLayout()
Any ideas on why the content wouldn't arrange would be appreciated cause its driving me nuts
I'm not sure why it works for you sometimes but not others. But a grid has the inherent ability to dynamically resize itself and its contents. A canvas doesn't (you'd have to handle that manually in code).
If you change your canvas to a grid does it work? A grid has slightly more overhead than a canvas but it sounds to me like you need its functionality anyway.

Resources