From fb20463449363dc6fdc7e8222726075ae1f3ef4b Mon Sep 17 00:00:00 2001 From: David Richardson Date: Sat, 13 Mar 2021 21:10:29 -0700 Subject: [PATCH 01/13] Fix Java version check to cleanly identify both Oracle and OpenJDK variants Set minimum supported version to 8 to simplify this check. Java 8 is the last variant from Oracle to be free and unencumbered, and is classified LTS. It is also available from OpenJDK. --- bootstrap.sh | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index e8480c33c..af1e1b0d1 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -130,17 +130,14 @@ function check_install_environment () { exit 1 fi - # make sure user is running the Sun JVM or OpenJDK >= 6b18 - java_version=$(java -version 2>&1) - echo $java_version | grep OpenJDK > /dev/null - if [ "$?" = "0" ]; then # OpenJDK: make sure >= 6b18 - openjdk_version=$(echo "$java_version" | grep "OpenJDK Runtime Environment") - openjdk_version_key=$(echo $openjdk_version | egrep -o '[0-9]\-?b[0-9]+') - if [ $(echo $openjdk_version_key | tr -d 'b' | tr -d '-') -lt 618 ]; then - echo "Error: Narwhal is not compatible with your version of OpenJDK: $openjdk_version." - echo "Please upgrade to OpenJDK >= 6b18 or switch to the Sun JVM. Then re-run bootstrap.sh." - exit 1 - fi + # Support Java version 8 or greater + # This is the LTS and last free/unencumbered version from Oracle + # It is also provided by OpenJDK + java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1) + if [ "$java_version" -lt "8" ]; then + echo "Error: Narwhal is not compatible with your the installed Java version: $java_version." + echo "Please upgrade to either Oracle or OpenJDK >= version 7. Then re-run bootstrap.sh." + exit 1 fi } From 8e026279ac3e1da7f7804177d087d7b1e67352ac Mon Sep 17 00:00:00 2001 From: daboe01 Date: Thu, 8 Jul 2021 21:28:42 +0200 Subject: [PATCH 02/13] fixed: CPButton's images were lost when becoming disabled --- AppKit/CPButton.j | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AppKit/CPButton.j b/AppKit/CPButton.j index c5bc8a2b5..e3d9b7bdc 100644 --- a/AppKit/CPButton.j +++ b/AppKit/CPButton.j @@ -380,6 +380,8 @@ CPButtonImageOffset = 3.0; _bezelState = CPThemeStateNormal; [self setValue:anImage forThemeAttribute:@"image" inState:_bezelState]; + // if we omit this, images will disappear as soon as the button becomes disabled + [self setValue:anImage forThemeAttribute:@"image" inState:_bezelState.and(CPThemeStateDisabled)]; } - (CPImage)image From eba1b2f9993acf08d5433f16e43435c137be8f08 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Thu, 29 Jul 2021 11:39:42 +0200 Subject: [PATCH 03/13] Fixed: CPSearchField's bezel did not resize (#2987) Co-authored-by: Didier Korthoudt --- AppKit/CPSearchField.j | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/AppKit/CPSearchField.j b/AppKit/CPSearchField.j index 720ed9344..2084ab717 100644 --- a/AppKit/CPSearchField.j +++ b/AppKit/CPSearchField.j @@ -819,7 +819,7 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat positioned:CPWindowAbove relativeToEphemeralSubviewNamed:nil]; } - else if (!_contentView) + else { var bezelView = [self layoutEphemeralSubviewNamed:@"bezel-view" positioned:CPWindowBelow @@ -827,9 +827,10 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat [bezelView setBackgroundColor:bezelColor]; - _contentView = [self layoutEphemeralSubviewNamed:@"content-view" - positioned:CPWindowAbove - relativeToEphemeralSubviewNamed:@"bezel-view"]; + if (!_contentView) + _contentView = [self layoutEphemeralSubviewNamed:@"content-view" + positioned:CPWindowAbove + relativeToEphemeralSubviewNamed:@"bezel-view"]; } if (_contentView) From 09f49c4afa083ecba44dd2556040602150607c31 Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Thu, 29 Jul 2021 12:38:25 +0200 Subject: [PATCH 04/13] Fixed: CPButton should not have the same label text size whatever the control size (#2990) Adding font size definitions to Aristo2. --- AppKit/Themes/Aristo2/ThemeDescriptors.j | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AppKit/Themes/Aristo2/ThemeDescriptors.j b/AppKit/Themes/Aristo2/ThemeDescriptors.j index 67627ba6a..4f4825d82 100644 --- a/AppKit/Themes/Aristo2/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo2/ThemeDescriptors.j @@ -233,6 +233,7 @@ var themedButtonValues = nil, [@"content-inset", CGInsetMake(0.0, 5.0, 0.0, 5.0), [CPThemeStateControlSizeSmall, CPThemeStateBordered]], [@"nib2cib-adjustment-frame", CGRectMake(-3.0, 6.0, 0.0, 0.0), [CPThemeStateControlSizeSmall, CPThemeStateBordered]], + [@"font", [CPFont boldSystemFontOfSize:11.0], [CPThemeStateControlSizeSmall, CPThemeStateBordered]], // RoundRect CPThemeStateControlSizeMini [@"bezel-color", @@ -256,6 +257,7 @@ var themedButtonValues = nil, [@"content-inset", CGInsetMake(0.0, 2.0, 2.0, 2.0), [CPThemeStateControlSizeMini, CPThemeStateBordered]], [@"nib2cib-adjustment-frame", CGRectMake(0.0, 14.0, 0.0, 0.0), [CPThemeStateControlSizeMini, CPThemeStateBordered]], + [@"font", [CPFont boldSystemFontOfSize:10.0], [CPThemeStateControlSizeMini, CPThemeStateBordered]], // Rounded [@"bezel-color", From 4b28d0c38b3413f863ebb1604035071ebdb74038 Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Fri, 6 Aug 2021 12:17:07 +0200 Subject: [PATCH 05/13] Fixed: setTextColor on a CPTextField would not take visual effect before an event (#2993) --- AppKit/CPTextField.j | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index dff268244..ba46d5d1c 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -2020,6 +2020,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); } [self setValue:placeholderColor forThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder]; + + [self layoutSubviews]; } - (void)viewDidHide From 8570476cff399bc57840aa745d18b48eb3531069 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Wed, 6 Oct 2021 12:18:51 +0200 Subject: [PATCH 06/13] New: Added link to install the new Node version --- README.markdown | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 5b240428a..f2e3a4ccf 100644 --- a/README.markdown +++ b/README.markdown @@ -36,7 +36,9 @@ However, you can also work on other platforms using only a simple text editor. Getting Started --------------- -To write you first application, [download the starter package](http://www.cappuccino-project.org/#download). +To write you first application, [download the starter package](http://cappuccino.dev/#download). + +To try our new Node (alpha) version of the Cappuccino framework, [check the Node installation instructions](https://github.com/cappuccino/cappuccino/wiki/node) To contribute to Cappuccino, please read here: [Getting and Building the Source](https://github.com/cappuccino/cappuccino/wiki/Getting-and-building-the-source). From a49a20e2c26c248ba6fa37520d58af4bbb9b8611 Mon Sep 17 00:00:00 2001 From: David Richardson Date: Tue, 19 Oct 2021 00:31:54 -0600 Subject: [PATCH 07/13] Fixed: nib2cib under Xcode 13 (#3006) Backwards-compatible changes to accommodate different ibtool output from Xcode 13 onwards --- Tools/nib2cib/Converter.j | 48 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/Tools/nib2cib/Converter.j b/Tools/nib2cib/Converter.j index 330d3c526..74fe8bedd 100644 --- a/Tools/nib2cib/Converter.j +++ b/Tools/nib2cib/Converter.j @@ -36,6 +36,7 @@ var FILE = require("file"), OS = require("os"), + SYSTEM = require("system"), SharedConverter = nil; @@ -97,6 +98,10 @@ ConverterConversionException = @"ConverterConversionException"; if (inferredFormat === NibFormatMac) var convertedData = [self convertedDataFromMacData:nibData]; else + // TODO: this is insufficient to fully confirm the xib file is valid. + // Xcode offers to upgrade older xib file formats when they are opened in Interface Builder + // but this may not happen if a project is recompiled without opening the xib. + // We should perform the same check here and offer to upgrade the file format. [CPException raise:ConverterConversionException reason:@"nib2cib does not understand this nib format."]; if ([outputPath length]) @@ -112,18 +117,51 @@ ConverterConversionException = @"ConverterConversionException"; var temporaryNibFilePath = "", temporaryPlistFilePath = ""; + var PROJECT_ROOT_DIR = SYSTEM.env["PWD"]; + var PROJECT_BUILD_DIR = FILE.join(PROJECT_ROOT_DIR, "Build"); + var TMP_DIR = FILE.join(PROJECT_BUILD_DIR, "tmp"); + + // System /tmp folder was previously used for ephemeral conversion artifacts + // In more recent versions of macOS, access permissions can be insufficient + // without using sudo. + // Additionally, temporary folders and files in /tmp were not being + // namespaced. This risks collisions + // between distinct xib files - ones named identically but in different project folders. + // Using a tmp folder in the project's Build folder resolves both issues. + // Leaving the tmp folder visible is an advantage when debugging failed conversions. + + // Does Build folder exist? If not, create it + CPLog.info("\nCreating temporary directories for conversion process:"); + if(!FILE.isDirectory(PROJECT_BUILD_DIR)) + { + CPLog.info("Create 'Build' directory: " + PROJECT_BUILD_DIR); + FILE.mkdir(PROJECT_BUILD_DIR); + } + + // Does tmp folder exist? If not, create it + if(!FILE.isDirectory(TMP_DIR)) + { + CPLog.info("Create 'tmp' directory: " + TMP_DIR); + FILE.mkdir(TMP_DIR); + } + try { if ([outputPath length]) { // Compile xib or nib to make sure we have a non-new format nib. - temporaryNibFilePath = FILE.join("/tmp", FILE.basename(aFilePath) + ".tmp.nib"); + temporaryNibFilePath = FILE.join(TMP_DIR, FILE.basename(aFilePath) + ".tmp.nib"); try { var p = OS.popen(["/usr/bin/ibtool", aFilePath, "--compile", temporaryNibFilePath]); - if (p.wait() === 1) + var error; + while (error = p.stderr.read()) CPLog.info("IBTool error(" + typeof error + "): '" + error + "'"); + var wait = p.wait(); + if (wait === 1) { + CPLog.info(error); [CPException raise:ConverterConversionException reason:@"Could not compile file: " + aFilePath]; + } } finally { @@ -131,13 +169,17 @@ ConverterConversionException = @"ConverterConversionException"; p.stdout.close(); p.stderr.close(); } - } else { temporaryNibFilePath = aFilePath; } + // Check if output path results in a directory + if (FILE.isDirectory(temporaryNibFilePath)) { + temporaryNibFilePath = FILE.join(temporaryNibFilePath, "keyedobjects.nib"); + } + // Convert from binary plist to XML plist var temporaryPlistFilePath = FILE.join("/tmp", FILE.basename(aFilePath) + ".tmp.plist"); From b7d7368ce6658c31ad6458a7c8ce5e30623e0c36 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Tue, 9 Nov 2021 11:49:30 +0100 Subject: [PATCH 08/13] Fixed: Include the Node build status badge at top --- README.markdown | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index f2e3a4ccf..fcb5cf5c1 100644 --- a/README.markdown +++ b/README.markdown @@ -1,4 +1,6 @@ -[![Build Status](https://travis-ci.org/cappuccino/cappuccino.svg?branch=master)](https://travis-ci.org/cappuccino/cappuccino) [![Join the chat at https://gitter.im/cappuccino/cappuccino](https://badges.gitter.im/cappuccino/cappuccino.svg)](https://gitter.im/cappuccino/cappuccino?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://travis-ci.org/cappuccino/cappuccino.svg?branch=master)](https://travis-ci.org/cappuccino/cappuccino) +![Node build](https://github.com/cappuccino/cappuccino/actions/workflows/BuildAndTest.yml/badge.svg?branch=node) +[![Join the chat at https://gitter.im/cappuccino/cappuccino](https://badges.gitter.im/cappuccino/cappuccino.svg)](https://gitter.im/cappuccino/cappuccino?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Welcome to Cappuccino! ====================== From 49574d1c54bd4efbb84c982c7c2a17a3be79cab8 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Tue, 9 Nov 2021 12:41:01 +0100 Subject: [PATCH 09/13] Fixed: Node build badge can be clicked to actions --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index fcb5cf5c1..7c77342dd 100644 --- a/README.markdown +++ b/README.markdown @@ -1,5 +1,5 @@ [![Build Status](https://travis-ci.org/cappuccino/cappuccino.svg?branch=master)](https://travis-ci.org/cappuccino/cappuccino) -![Node build](https://github.com/cappuccino/cappuccino/actions/workflows/BuildAndTest.yml/badge.svg?branch=node) +[![Node build status](https://github.com/cappuccino/cappuccino/actions/workflows/BuildAndTest.yml/badge.svg?branch=node)](https://github.com/cappuccino/cappuccino/actions/workflows/BuildAndTest.yml) [![Join the chat at https://gitter.im/cappuccino/cappuccino](https://badges.gitter.im/cappuccino/cappuccino.svg)](https://gitter.im/cappuccino/cappuccino?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Welcome to Cappuccino! From 3179d568793b6a62c09eda85d6737a623050abf2 Mon Sep 17 00:00:00 2001 From: David Richardson Date: Tue, 23 Nov 2021 05:41:30 -0700 Subject: [PATCH 10/13] Fixed: Include commented code to hide mainMenu (#3008) Add commented-out code to capp gen NibApplication template. The technique itself is easy to forget and not obvious to newcomers. It is included in the standard capp gen application template and added here for completeness. --- Tools/capp/Resources/Templates/NibApplication/AppController.j | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/capp/Resources/Templates/NibApplication/AppController.j b/Tools/capp/Resources/Templates/NibApplication/AppController.j index cb34bb65c..3f911c7e5 100644 --- a/Tools/capp/Resources/Templates/NibApplication/AppController.j +++ b/Tools/capp/Resources/Templates/NibApplication/AppController.j @@ -18,6 +18,8 @@ - (void)applicationDidFinishLaunching:(CPNotification)aNotification { // This is called when the application is done loading. + // Uncomment the following line to hide the standard menu bar. + // [CPMenu setMenuBarVisible:NO]; } - (void)awakeFromCib From ccc6007bab702ba22ecd5b28faf2935f10102426 Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Tue, 23 Nov 2021 13:42:36 +0100 Subject: [PATCH 11/13] Fixed: Bezel state instance variable _bezelState must remove current state when changing to a new state (#3001) If the bezel state was changed and some attribute was set like an "image". The image would not be found as there were two states active and it would not match. --- AppKit/CPButton.j | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AppKit/CPButton.j b/AppKit/CPButton.j index e3d9b7bdc..7853d1d5d 100644 --- a/AppKit/CPButton.j +++ b/AppKit/CPButton.j @@ -973,7 +973,11 @@ CPButtonImageOffset = 3.0; _bezelStyle = aBezelStyle; if (_bezelState && newState) + { + if (currentState) + _bezelState =_bezelState.without(currentState); _bezelState = _bezelState.and(newState); + } else _bezelState = newState || CPThemeStateNormal; From b66690e304b18b083fe6cd0e71a1789228bc0a84 Mon Sep 17 00:00:00 2001 From: David Richardson Date: Tue, 23 Nov 2021 05:45:10 -0700 Subject: [PATCH 12/13] New: Implement missing indexPath method for CPTreeNode (#2999) --- AppKit/CPTreeNode.j | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/AppKit/CPTreeNode.j b/AppKit/CPTreeNode.j index 9e2871218..0f5f88a33 100644 --- a/AppKit/CPTreeNode.j +++ b/AppKit/CPTreeNode.j @@ -50,6 +50,31 @@ return self; } +- (CPIndexPath)indexPath +{ + if (_parentNode != nil) + { + var path; + var index; + + index = [[_parentNode childNodes] indexOfObject:self]; + path = [_parentNode indexPath]; + + if (path != nil) + { + return [path indexPathByAddingIndex:index]; + } + else + { + return [CPIndexPath indexPathWithIndex:index]; + } + } + else + { + return nil; + } +} + - (BOOL)isLeaf { return [_childNodes count] <= 0; From 37756a58534271b1104fe494179b57c511c4fa5e Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Tue, 23 Nov 2021 13:47:54 +0100 Subject: [PATCH 13/13] Fixed: nib2cib: checks if there's a defined superview in resizeWithOldSuperviewSize (#2995) --- AppKit/CPView.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppKit/CPView.j b/AppKit/CPView.j index 9219f7534..cce918d6f 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -1479,7 +1479,7 @@ var CPViewHighDPIDrawingEnabled = YES; { var mask = [self autoresizingMask]; - if (mask === CPViewNotSizable) + if ((mask === CPViewNotSizable) || !_superview) return; var frame = _superview._frame,