discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GNUstep app fails on Ubuntu 16 - found workaround


From: Fred Kiefer
Subject: Re: GNUstep app fails on Ubuntu 16 - found workaround
Date: Fri, 8 May 2020 17:42:51 +0200

It turns out that we do not limit the frame of a window on creation. The lines 
of code in NSWindow look like this:


 _frame = [NSWindow frameRectForContentRect: contentRect styleMask: aStyle];
 _minimumSize = NSMakeSize(_frame.size.width - contentRect.size.width + 1,
                            _frame.size.height - contentRect.size.height + 1);
 _maximumSize = NSMakeSize (10e4, 10e4);

Every attempt to set the size too big later on will be blocked, but doing so on 
creation is passed through. I will have to come up with a solution for this. 
Maybe just call setFrame: in the next line?

Fred

> Am 08.05.2020 um 17:29 schrieb Fred Kiefer <fredkiefer@gmx.de>:
> 
> HI Andreas,
> 
> 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.
> 
> 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 see a sensible way 
> we could fix this problem directly in GNUstep gui. The only way would be to 
> enforce some arbitrary limit for views and this is not possible as we may 
> have some coordinate transformation in place and seemingly huge values would 
> be converted to usable ones. As for the window enforcing limits there makes 
> sense but I vaguely remember that we already have code for that in place. 
> Although I am still looking for that limit.
> 
> Cheers,
> Fred
> 
> 
>> Am 08.05.2020 um 16:31 schrieb Andreas Höschler via Discussion list for the 
>> GNUstep programming environment <discuss-gnustep@gnu.org>:
>> 
>> 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
>> 
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]