If the cursor uses a solid fill (color) only it should be redrawn, and when it blinks "off" only the RubScrolledTextMorph (if it has a solid fill), and any of it submorphs which intersects with the damage area should be redrawn. (drawing is being called for the full window) The only area modified is that within the clipping rect of the canvas (damaged area). For non-complex drawing (system window only draws a rectangle with border) filling over a small area should not be noticeable performance wise (as long as the submorph tree is not too deep), but should be fixed. I think the best place to start looking at and improving is in WorldState >>#drawWorld:submorphs:invalidAreasOn: Best regards, Henrik -----Original Message----- From: Pharo-dev [mailto:pharo-dev-bounces@lists.pharo.org] On Behalf Of Esteban Lorenzano Sent: Sunday, May 22, 2016 9:50 PM To: Pharo Development List <pharo-dev@lists.pharo.org> Subject: Re: [Pharo-dev] weird tales about cursors and rectangle invalidations Hi, flash damaged areas is not showing me anything :( but still, you seems to be in agreement with me and what is happening *should not* happen, isnât? (drawing is being called for the full window) btw, this is not just a rubric problem, it happens if I put a PluggableTextMorph as well. cheers! Esteban
On 22 May 2016, at 21:28, Henrik Nergaard <henrik.nergaard@uia.no> wrote:
Hi Esteban,
To see the damage live: SystemSettings->Tools->Debugging->Flash damaged morphic region.
Redrawing: Only morphs whose area is within the visible draw region of the canvas (the damaged area) needs to be redrawn, so if a morph fullbounds is not intersecting with this area it will not be drawn, and its submorphs will not check deeper in this submorph hierarchy. The exclusion is done in #fullDrawOn: by "(aCanvas isVisible: self fullbounds) ifFalse: [ ^self ]. So if the cursor reports a damage rectangle only morphs intersecting with that area needs to be redrawn (there is also some layering mechanism IIRC so that it should only re-draw the visible layers in that area, and not morphs which are covered by their submorphs).
DamageRecorder: The damage recorder do not know about any layering of morphs when it records damage. This means that if there is two overlapping windows in the World, and the window in the back triggers an invalid area which intersects with the window above, it will have to be redraw for that area as well even though it is not necessary.
There is also the issue where multiple small areas close to each other need multiple passes to be completed. If the damage recorder has damage in (10@10 corner: 20@20) and (10@30 corner: 20@40) a morph with bounds (0@0 corner: 50@50) will be redrawn twice during that cycle.
Rubric: There is some issues with how rubric handle changes, which causes blinking the cursor to do way to much work that it actually have to do, I think it also invalidates the whole selection and needs to redraw that as well.
Best regards, Henrik
-----Original Message----- From: Pharo-dev [mailto:pharo-dev-bounces@lists.pharo.org] On Behalf Of Esteban Lorenzano Sent: Sunday, May 22, 2016 8:36 PM To: Pharo Development List <pharo-dev@lists.pharo.org> Subject: [Pharo-dev] weird tales about cursors and rectangle invalidations
Hi,
Iâve been playing a bit today with something that is puzzling me and I need some more eyes in what Iâm doing, because it might be that Iâm understanding everything wrong⦠but if not, then, huston, we have a bug. So, play with me⦠you need to create this:
SystemWindow subclass: #XSystemWindow instanceVariableNames: 'iteration' classVariableNames: '' package: âXXX'
XSystemWindow>>initialize super initialize. iteration := 0.
XSystemWindow>>drawOn: aCanvas âDo not use transcript because it does even more crazy stuff" Stdio stdout << (iteration := iteration + 1) asString; cr; lf. super drawOn: aCanvas
Then execute this in a playground:
XSystemWindow new addMorph: (RubScrolledTextModel new newScrolledText) fullFrame: LayoutFrame identity; openInWorld.
and then you can watch in your stdout how full window redraws with cursor blinking (it stops when window loses focus).
This happens because cursor is displayed with lapsus of 700ms and is just a draw of a line with a color who is set to itâs opposite each time. Then it does "color: shownColorâ and #color: sends #changed who finalise in #invalidRect. I always thought that this invalidation mechanism works by recording âdamaged areasâ, then collecting morphs with that area and triggering the redraw of that morph. With this in mind, cursor should trigger an invalidation of itâs own area (a small portion of the screen, as you can see). I could understand that a cursor triggers the text area redraw (but that would be a âdesign flawâ, IMO)⦠now, what I cannot understand is why blink a cursor triggers the redraw of a FULL WINDOW. When in Nautilus, that means each cursor blink triggers the redraw of one tree, four lists, some buttons and finally, the text area. IMO, this is not acceptable.
What do you think?
Esteban