gnb@bby.oz.au (Gregory N. Bond) (04/17/91)
[This has been sent to xbugs] X Window System Bug Report xbugs@expo.lcs.mit.edu VERSION: R4, MIT tape patched to fix-18 CLIENT MACHINE and OPERATING SYSTEM: Any DISPLAY TYPE: Any WINDOW MANAGER: Any AREA: Xt SYNOPSIS: XtSetValues assumes all non-widget objects are RectObjs DESCRIPTION: The XtSetValues handling of redraws is flawed for Objects that are not widgets and not subclasses of RectObj. When a widget set_values routine returns True, XtSetValues forces a redraw by doing an XClearArea on the widget window. If the object is not a widget, XtSetValues finds the nearest widget ancestor and, treating the object as a RectObj, clears the portion of the ancestor window that is "covered" by the RectObj. If the object is not a RectObj, this will be wrong and a random part of the window will be cleared. If the data wrongly read as the rectangle coords is sufficiently perverse, a BadValue error may be generated (I think, I've not actually seen one). It doesn't seem to be actually causing any problems for me, but perhaps I am just lucky with the data I have in the "rectangle" fields (they overlap 2 Pixel values and an integer in the subclass I am using, which means XtSetValues was seing x=<small number>, y=0, width=<small number>, height=0, borderwidth=0). It is not clear what the correct action is in this case. One approach is to generate a synthetic expose event on the window with an empty region. The fix below handles it by just not doing any redraws for changes on non-RectObj objects. Whatever is chosen will need to be documented! REPEAT BY: Examine the source code! SAMPLE FIX: *** SetValues.c.DIST Wed Apr 17 17:16:24 1991 --- SetValues.c Wed Apr 17 17:17:35 1991 *************** *** 262,268 **** if (redisplay && XtIsRealized(w) && !w->core.being_destroyed) XClearArea (XtDisplay(w), XtWindow(w), 0, 0, 0, 0, TRUE); } else { /*non-window object */ ! if (redisplay && ! cleared_rect_obj ) { Widget pw = _XtWindowedAncestor(w); if (XtIsRealized(pw) && !pw->core.being_destroyed) { RectObj r = (RectObj)w; --- 262,268 ---- if (redisplay && XtIsRealized(w) && !w->core.being_destroyed) XClearArea (XtDisplay(w), XtWindow(w), 0, 0, 0, 0, TRUE); } else { /*non-window object */ ! if (XtIsRectObj(w) && redisplay && ! cleared_rect_obj ) { Widget pw = _XtWindowedAncestor(w); if (XtIsRealized(pw) && !pw->core.being_destroyed) { RectObj r = (RectObj)w; -- Gregory Bond, Burdett Buckeridge & Young Ltd, Melbourne, Australia Internet: gnb@melba.bby.oz.au non-MX: gnb%melba.bby.oz@uunet.uu.net Uucp: {uunet,pyramid,ubc-cs,ukc,mcvax,prlb2,nttlab...}!munnari!melba.bby.oz!gnb
gnb@bby.oz.au (Gregory N. Bond) (04/18/91)
Red faces time, folks. The bug report I posted was wrong. It turns out the check for RectObj was made a page or so higher in the code. I missed it for some reason (perhaps I deleted a curly and the editor mismatched them...) I thought it explained a few problems I was having, but it didn't. Sincerest apologies to all concerned. You can stop mailing me now. Greg, Penitent. -- Gregory Bond, Burdett Buckeridge & Young Ltd, Melbourne, Australia Internet: gnb@melba.bby.oz.au non-MX: gnb%melba.bby.oz@uunet.uu.net Uucp: {uunet,pyramid,ubc-cs,ukc,mcvax,prlb2,nttlab...}!munnari!melba.bby.oz!gnb
marbru@auto-trol.com (Martin Brunecky) (04/19/91)
In article <1991Apr17.073327.12784@melba.bby.oz.au> gnb@bby.oz.au (Gregory N. Bond) writes: >[This has been sent to xbugs] > > The XtSetValues handling of redraws is flawed for Objects that > are not widgets and not subclasses of RectObj. When a widget > set_values routine returns True, XtSetValues forces a redraw > by doing an XClearArea on the widget window. If the object is > not a widget, XtSetValues finds the nearest widget ancestor > and, treating the object as a RectObj, clears the portion of > the ancestor window that is "covered" by the RectObj. If the > object is not a RectObj, this will be wrong and a random part > of the window will be cleared. If the data wrongly read as > the rectangle coords is sufficiently perverse, a BadValue > error may be generated (I think, I've not actually seen one). > > It doesn't seem to be actually causing any problems for me, .... I had more than my share of troubles with SIMILAR bug in Motif 1.0 "flavor" of XtIntrinsics. We ended-up padding all our "objects" with "RectObj" fields, initialized appropriately. ick, ick, ick. However, this WAS Motif R3++ code, and it WAS really bad. I looked at the R4 code several times, and it does NOT seem to have this problem (at least not THAT bad). UNLESS there is a "buggy" widget. The MIT code assumes that "Objects" will be "reasonable" and set_values will return redisplay = FALSE. It also assumes that constraint widgets will be "reasonable", and for "Object" children their constraint_set_values will return FALSE. So, if the objects in question are not buggy - no problem, as far as I can tell. However, the world is not a perfect place. Though I would like all the widgets to be perfect, I doubt it will ever happen. AS in this case XtIntrinsics can compensate for "buggy" widgets, I'd recomend to change the code as suggested. > It is not clear what the correct action is in this case. One > approach is to generate a synthetic expose event on the window > with an empty region. Why ? If there is a window/rectangle, XClearArea will do the job. There, however, is another, related problem. SetValues descends the class hierarchy top-down. If my widget's superclass said "yes, I need to redisplay", my widget has no way to change that - even though because of changed semantics my class in fact may not need to redisplay at all. So what I need is a tri-state return from SetValues: TRUE = this class does require redisplay FALSE = this class does not require redisplay UNDO = even if superclass required redisplay, it is not needed -- =*= Opinions presented here are solely of my own and not those of Auto-trol =*= Martin Brunecky {...}sunpeaks!auto-trol!marbru (303) 252-2499 (sometimes also: marbru@auto-trol.COM ) Auto-trol Technology Corp. 12500 North Washington St., Denver, CO 80241-2404