Closed Bug 239074 Opened 20 years ago Closed 16 years ago

onpaint events not working

Categories

(Core :: DOM: Events, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: alex, Unassigned)

References

()

Details

(Whiteboard: [firebug-p3])

Mozilla doesn't seem to generate any onpaint events.
Testcase at http://www.croczilla.com/~alex/onpaint.html:
<html>
  <head>
    <script>
      function init() {
        window.onpaint=function(){alert("paint")};
      }
    </script>
  </head>

  <body onload="init()">
  </body>
</html>

This html file never pops up any alert boxes. Other related events such as
onresize work fine.
I don't believe we've ever done this, in fact... and should we start?  onpaint
is "DOM0", right?
I (In reply to comment #2)
> I don't believe we've ever done this, in fact... and should we start?  onpaint
> is "DOM0", right?

Yeah, this is DOM0 afaik. There is code that suggests that this was working once
(or was planned). E.g. nsEventReceiverSH (dom/src/base/nsDOMClassInfo.cpp) knows
about "paint" as a valid event name.
Also our documentation mentions it:
http://www.mozilla.org/docs/dom/domref/dom_window_ref69.html

(In reply to comment #3)
> Why do we want to do this?

I don't know whether there are any legitimate uses.
I was wanting to use it for timing document loads including painting from JS.
From a casual reading of widget/src/windows/nsWindow.cpp I got the impression
that this DOM event would be fired after painting (nsWindow::DispatchEvent(){...
mEventListener->ProcessEvent() ... }).
Here's a reason I can think of to do this:  I've had cases where I've had to use JavaScript to position stuff absolutely in a relative manner, by calculating from surrounding element sizes and positions, etc... and using resize/scroll/etc events I'm able to do reasonably well with this technique... except in one case:  when the user changes their font size preference... there's no event for me to capture that I'm aware of!  Currently the user has to refresh the window to get it to redraw correctly in such a case.  Wouldn't a paint event help me solve this?  For surely it would be repainting the window in such a case and firing this event. Then I could simply run through my routine and see if anything needed to be moved during a paint event.  Maybe I wouldn't even need to bother with the other events, we'll see...
Probably we should fire on onresize event when the text size changes. Sorta bogus but it would work for all those people who do manual layout on onresize.
An xulrunner app I'm developing displays a grid of images. It uses a as many columns as it can fit in the window size. Obviously I need to know how big the area is to do this and right now I have to put in about a 100ms delay after the load event before attempting to read that since at load the size is 0.

Presumably this event would be after layout has been done so I would actually get a sensible size without the hacky delay so this would be real useful to me.
Whiteboard: [firebug-p3]
I was wondering why paint events weren't working like I remember them once upon a time... now I know.

Paint events are also useful when you want to pay attention to mutations in a page - and ignore those that don't change the rendering.  For instance, I have a bunch of mutation event listeners which - simply by being attached - degrade performance.  It'd be so much easier with a paint event.
We've implemented MozAfterPaint.
Status: NEW → RESOLVED
Closed: 16 years ago
Resolution: --- → FIXED
There is now MozAfterPaint event, that might be what you need.
https://developer.mozilla.org/en/Gecko-Specific_DOM_Events
Bug 450930 is the place where it was implemented.

Although, I really would find it useful to know the difference between painting
because of a scroll and painting because of some invalidation.
Also, for me, it would be very useful to be able to listen for MozAfterPaint events on certain elements only, instead of the whole window.
Sorry for spamming, what I especially would like is to detect when an elements has changed in width/height. So a way to detect that kind of invalidation would be great.
I think that we still need this event. This is a prefect opportunity to allow JavaScript developers to greatly improve the performance of web applications that heavily modify the DOM or CSS. Currently Developers has tried solving DOM performance issues by shoving all new nodes into a DOM fragment, then into the DOM tree, so the browser only reflows once and prevent it from having a 'cardiac arrest', an out of control cascade of reflows.

What if this event could block reflow by returning false? This would enable JavaScript to insert as many nodes and mess with the page without a cascade of reflows.

If you were to build a display system from scratch for an operating system would you not have a way to manually control draw cycles? We are not just coding documents anymore. If we really want to empower developers then we need to give them a way of controlling reflow. I think this is the most consistent.

I prepose the following.

1.) Gecko wants to redraw because something in the DOM has changed.
2.) It fires an onpaint event.
3.) If a function is binded and that function returns false the reflow is delayed a cycle.
4.) If the binded function continues to return false the redraw will continue to be delayed.
5.) If the function returns anything other than false, the page redraws once using the current DOM tree and CSS.

Here are some possible use cases:
- Single page applications.
- Libraries that handle the DOM and/or CSS such as jQuery
- Games that use the DOM (Though this might not be the best idea).
- Possibly canvas, but that depends on how Gecko handles canvas redraws.
Assignee: events → nobody
OS: Windows 2000 → All
QA Contact: ian → events
Hardware: x86 → All
Robert: Your suggestion generated a bit of buzz on reddit, see sporkexec's suggestion for an improvement to the idea:

http://www.reddit.com/r/javascript/comments/ljm7p/should_javascript_be_able_to_control_reflow/c2t8fva
I think there is already something for that that might be doing what is wanted there:
http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html

Implemented in Mozilla as  mozRequestAnimationFrame :
http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/base/nsIDOMWindow.idl#421
That would not address the use case of comment 5.

The use case of comment 14 is already solved: we don't reflow while a script is running unless the script _explicitly_ requests layout information.  The "build the DOM in a document fragment" hacks are not really that relevant in a world with lazy reflow, lazy style reresolution, and lazy frame construction (which is where we are now).  Or is comment 14 talking about preventing reflow while running things off timeouts?
(In reply to Jacob Hansson from comment #15)
> Robert: Your suggestion generated a bit of buzz on reddit, see sporkexec's
> suggestion for an improvement to the idea:
> 
> http://www.reddit.com/r/javascript/comments/ljm7p/
> should_javascript_be_able_to_control_reflow/c2t8fva

Yea I see that. He has a good point and so I've revised my proposal. http://www.reddit.com/r/javascript/comments/lk6ck/how_javascript_reflow_control_might_look
You need to log in before you can comment on or make changes to this bug.