Hi Fred,
> that is a very interesting analysis you provided. Could you tell us a bit
> more about the images you are using? Or to be concrete, what is the size of
> one of these images? If these images report such huge values for their height
> this would explain the behaviour you are seeing.
The images are rather tiny. Here is the one that caused the problem in one of
the forms:
>
> In NSButtonCell the computation of cellSize relies directly on the value
> reported by the image. It would also be interesting to know, which value gets
> used for the image position of the button cell.
I don't set that. So I guess it's a default position!? Let's see ...
@implementation NSButton (sizeToContent)
- (void)sizeToFit
{
NSSize size = [_cell cellSize];
if (size.height > 10000.0)
{
NSLog(@"Reporting button::imagePosition %d", [self imagePosition]);
NSLog(@"Reporting _cell::imagePosition %d", [_cell imagePosition]);
}
[self setFrameSize: size];
}
@end
This reports
2020-05-08 17:47:41.464 SOObjectBrowser[11742:11742] Reporting
button::imagePosition 2
2020-05-08 17:47:41.464 SOObjectBrowser[11742:11742] Reporting
_cell::imagePosition 2
2020-05-08 17:47:41.464 SOObjectBrowser[11742:11742] Got height
10000004.000000. We correct this ...
2020-05-08 17:47:41.465 SOObjectBrowser[11742:11742] Reporting
button::imagePosition 2
2020-05-08 17:47:41.465 SOObjectBrowser[11742:11742] Reporting
_cell::imagePosition 2
2020-05-08 17:47:41.465 SOObjectBrowser[11742:11742] Got height
10000004.000000. We correct this ...
Thanks,
Andreas
>
>
>> Am 08.05.2020 um 16:31 schrieb Andreas Höschler via Discussion list for the
>> GNUstep programming environment <[email protected]>:
>>
>> In the meanwhile I have inserted an [NSException raise:...] into
>> /libs-back/Source/x11/XWindowBuffer.m
>>
>> if (!wi->ximage)
>> {
>> NSLog(@"Warning: XShmCreateImage failed!");
>> NSLog(@"Falling back to normal XImage (will be slower).");
>> goto no_xshm;
>> }
>> wi->shminfo.shmid = shmget(IPC_PRIVATE,
>> wi->ximage->bytes_per_line * wi->ximage->height,
>> IPC_CREAT | 0700);
>>
>> if (wi->shminfo.shmid == -1)
>> {
>> NSLog(@"Warning: shmget() failed: %m.");
>> NSLog(@"Falling back to normal XImage (will be slower).");
>>
>> [NSException raise:NSInternalInconsistencyException
>> format:@"asas"]; // <-- remove this
>>
>> XDestroyImage(wi->ximage);
>> goto no_xshm;
>> }
>>
>> to get a backtrace of what triggers the shmget() problem and got this
>>
>> #0 -[NSException raise] (self=0x46c75c0, _cmd=0x7ffff6ac64e0
>> <_OBJC_SELECTOR_TABLE+480>) at NSException.m:1574
>> #1 0x00007ffff6565bba in +[NSException raise:format:arguments:]
>> (self=0x7ffff6ac6020 <_OBJC_Class_NSException>,
>> _cmd=0x7ffff6ac64b0 <_OBJC_SELECTOR_TABLE+432>, name=0x7ffff6ac59e0
>> <_OBJC_INSTANCE_4>, format=0x7fffee2ccd50 <_OBJC_INSTANCE_12>,
>> argList=0x7fffffffca10) at NSException.m:1465
>> #2 0x00007ffff6565b01 in +[NSException raise:format:] (self=0x7ffff6ac6020
>> <_OBJC_Class_NSException>, _cmd=0x7fffee2cd3b0 <_OBJC_SELECTOR_TABLE+176>,
>> name=0x7ffff6ac59e0 <_OBJC_INSTANCE_4>, format=0x7fffee2ccd50
>> <_OBJC_INSTANCE_12>) at NSException.m:1450
>> #3 0x00007fffee05d046 in +[XWindowBuffer windowBufferForWindow:depthInfo:]
>> (self=0x7fffee2cd280 <_OBJC_Class_XWindowBuffer>,
>> _cmd=0x7fffee2d2320 <_OBJC_SELECTOR_TABLE+320>, awindow=0x1072ce0,
>> aDI=0x7fffffffcba0) at XWindowBuffer.m:322
>> #4 0x00007fffee0620d7 in -[ARTGState(internal) stuff:GSSetDevice:::]
>> (self=0x1087990, _cmd=0x7fffee2d1840 <_OBJC_SELECTOR_TABLE+352>,
>> window=0x1072ce0,
>> x=1, y=10000547) at ARTGState.m:644
>> #5 0x00007fffee05e933 in -[ARTContext(ops) GSSetDevice:::] (self=0x3f7f2f0,
>> _cmd=0x7fffee2ca860 <_OBJC_SELECTOR_TABLE+1472>, device=0x1072ce0, x=1,
>> y=10000547) at ARTContext.m:164
>> #6 0x00007fffee04a30f in GSSetDevice (ctxt=0x3f7f2f0, device=0x1072ce0,
>> x=1, y=10000547) at
>> /usr/GNUstep/Local/Library/Headers/AppKit/DPSOperators.h:1153
>> #7 0x00007fffee052111 in -[XGServer(WindowOps) setWindowdevice:forContext:]
>> (self=0xa53760, _cmd=0x7fffee2ba080 <_OBJC_SELECTOR_TABLE+448>, win=164,
>> ctxt=0x3f7f2f0) at XGServerWindow.m:2683
>> #8 0x00007fffee022ed5 in -[GSContext initWithContextInfo:] (self=0x3f7f2f0,
>> _cmd=0x7ffff7d676e0 <_OBJC_SELECTOR_TABLE+3520>, info=0x46cad70)
>> at GSContext.m:226
>> #9 0x00007ffff78b598d in -[NSWindow _startBackendWindow] (self=0x108b160,
>> _cmd=0x7ffff7d67770 <_OBJC_SELECTOR_TABLE+3664>) at NSWindow.m:915
>> #10 0x00007ffff78b5d69 in -[NSWindow _initBackendWindow] (self=0x108b160,
>> _cmd=0x7ffff7d67890 <_OBJC_SELECTOR_TABLE+3952>) at NSWindow.m:967
>> #11 0x00007ffff78b66f7 in -[NSWindow
>> initWithContentRect:styleMask:backing:defer:] (self=0x108b160,
>> _cmd=0x7ffff3970980 <_OBJC_SELECTOR_TABLE+1888>,
>> contentRect=..., aStyle=15, bufferingType=2, flag=0 '\000') at
>> NSWindow.m:1100
>> #12 0x00007ffff370ed00 in -[GSMarkupTagWindow platformObjectInit]
>> (self=0x21f6c20, _cmd=0x7ffff3952c80 <_OBJC_SELECTOR_TABLE+2272>)
>> at GSMarkupTagWindow.m:180
>>
>> The corresponding code is
>>
>>
>> GSMarkupTagWindow:
>> ==========================
>> - (void)platformObjectInit
>> {
>> ...
>> NSLog(@"contentRect %@ style %d backingType %d",
>> NSStringFromRect(contentRect), style, backingType);
>> [self setPlatformObject:[_platformObject initWithContentRect:contentRect
>> styleMask:style backing:backingType defer:NO]];
>> ....
>> }
>>
>> and the output of the log line is
>>
>> 2020-05-08 13:42:59.862 SOSmartBrowser[29363:29363] _rootTagObject
>> <GSMarkupTagVBox: 0x86e5290> contentView h=-&- v=-&- <GSVBox: 0xdce1550>
>> f={x = 0; y = 0; width = 0; height = 0} b={x = 0; y = 0; width = 0; height =
>> 0}
>> 2020-05-08 11:43:19.108 SOObjectBrowser[28857:28857] contentRect {x = 20; y
>> = 20; width = 1022; height = 1.00005e+07} style 15 backingType 2
>>
>> Aha!! height = 1.00005e+07 looks a bit to large. Cocoa and the old GNUstep
>> tree got a long with this request. The more recent code seems to be a bit
>> pickier. :-)
>>
>> I dived a little deeper into the code and found that the following NSView
>> category method produces the unreasonable values.
>>
>> - (NSSize)minimumSizeForContent
>> {
>> NSRect oldFrame;
>> NSSize minimumSize;
>>
>> /* Save the oldFrame. */
>> oldFrame = [self frame];
>>
>> /* Resize the view to fit the contents ... this is the only
>> * way available in the AppKit to get the minimum size. */
>> [self sizeToFitContent];
>>
>> /* Get the minimum size by reading the frame. */
>> minimumSize = [self frame].size;
>> /* Restore the original frame. */
>> [self setFrame:oldFrame];
>> return minimumSize;
>> }
>>
>> more explicitly
>>
>> @implementation NSControl (sizeToContent)
>>
>> - (void)sizeToFitContent
>> {
>> [self sizeToFit];
>> }
>>
>> @end
>>
>> does and even more explicitly
>>
>> NSButton:: sizeToFit
>>
>> pico ./Source/NSControl.m
>>
>> /**<p>Resizes the NSControl to fits the NSControl's cell size.</p>
>> <p>See Also: [NSCell-cellSize]</p>
>> */
>> - (void) sizeToFit
>> {
>> [self setFrameSize: [_cell cellSize]];
>> }
>>
>> It turns out that the problem occurs on all forms that have NSButtons that
>> have been customised with
>>
>> image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
>> if (image)
>> {
>> [someButton setImage:image];
>> }
>>
>>
>> My first measure (ugly hack) was to do
>>
>> @implementation NSControl (sizeToContent)
>>
>> - (void)sizeToFitContent
>> {
>> [self sizeToFit];
>> NSSize size = [self frame].size;
>> if (size.height > 10000.0)
>> {
>> NSLog(@"Got height %f. We correct this ...", size.height);
>> [self setFrameSize: NSMakeSize(size.width, 24.0)]; // <-- just some
>> phantaise value
>> }
>> }
>>
>> @end
>>
>> This fixes the problem for me. The forms open and the app works nicely.
>>
>> The academic question remains what makes NSControl::sizeToFit to fail so
>> badly for buttons with images?
>>
>> Since others have hit this as well (see one of my mails from yesterday) this
>> should probably be addressed in the GNUstep code. Does this ring any bells?
>>
>> Thanks a lot,
>>
>> Andreas
>>
>
Mit freundlichen Grüßen,
Andreas Höschler
Managing Director
Smartsoft GmbH
Birkenweg 11a
D-21483 Gülzow
Phone 040 22820930-0
Fax 040 22820930-9
Web http://www.smartsoft.de <http://www.smartsoft.de/>
Email: [email protected] <mailto:[email protected]>
Steuernummer: 44/759/00826
Amtsgericht Hamburg, HRB 117172
Geschäftsführer: Andreas Höschler